Note that there are some explanatory texts on larger screens.

plurals
  1. POKey not found in a HashMap for a composite object
    text
    copied!<p>So, I made my own composite key in Java with 3 members </p> <pre><code>public class MyOwnKey{ int location; int length; String [] tokens; } </code></pre> <p>Now I create two objects using the constructor</p> <pre><code>String [] tokens = "Stackoverflow is great".split("\\s+"); Object key1 = new MyOwnKey(0,0,tokens) tokens = "Web is great".split("\\s+"); Object key2 = new MyOwnKey(0,0,tokens) </code></pre> <p>Now, I add the key in HashMap HashMap map = new HashMap(); map.put(key1,1);</p> <p>Now, this is the problem when I do contains key, it gives false;</p> <pre><code>**map.containsKey(key2) //returns false whereas it should return true.** </code></pre> <p>Just so that it makes sense:</p> <pre><code>key1.equals(key2) returns true </code></pre> <p>and the hashcode codes are also equal. <code>key1.hashCode() == key2.hashCode().</code> </p> <p>I have implemeneted my own version of hashCode, toEquals() and toCompare(). </p> <p>Not sure what's the problem.</p> <p>Here is the code</p> <pre><code>import java.io.DataOutput; import java.io.DataInput; import java.io.IOException; import org.apache.hadoop.io.WritableComparable; public class PatternGeneratorKey implements WritableComparable&lt;Object&gt; { private String [] tokens; int location; int length; StringBuffer _toString = null; public PatternGeneratorKey(){ tokens = new String[1]; location =0; length=1; } public PatternGeneratorKey(int location, int length, String [] tokens){ this.location = location; this.length = length; this.tokens= new String[tokens.length]; for(int i = 0; i &lt; tokens.length;i++){ this.tokens[i] = tokens[i]; } } public int compareTo(Object o) { if (!(o instanceof PatternGeneratorKey)) return -1; return this.compareTo((PatternGeneratorKey) o); } public void write(DataOutput out) throws IOException { out.writeInt(tokens.length); for(int i = 0; i&lt;tokens.length;i++){ out.writeUTF(tokens[i]); } out.writeInt(location); out.writeInt(length); } public void readFields(DataInput in) throws IOException { int l = in.readInt(); tokens = new String[l]; for(int i = 0; i &lt; l ; i++){ tokens[i] = in.readUTF(); } location = in.readInt(); length = in.readInt(); } public int compareTo(PatternGeneratorKey k) { if(this.tokens.length - this.length != k.tokens.length - k.length){ return this.tokens.length - this.length -( k.tokens.length - k.length); } if(this.location != k.location){ return this.location - k.location; } int i = 0 , j= 0; for(i = 0, j=0 ; i &lt; this.tokens.length &amp;&amp; j &lt; k.tokens.length;){ if(i == this.location ){ i = i + length; continue; } if( j == k.location){ j = j + k.length; continue; } if(!this.tokens[i].equalsIgnoreCase(k.tokens[j])){ return this.tokens[i].compareTo(k.tokens[j]); }else{ i++; j++; } } //TODO: add comparison on left out phrase return 0; } public int hashCode() { int hashCode=0; for(int i = 0; i &lt; tokens.length;){ if(i == location ){ i = i + length; continue; } hashCode += tokens[i++].hashCode(); } hashCode+= location + tokens.length; return hashCode; } public String toString(){ if(_toString == null){ _toString = new StringBuffer(); for(int k = 0; k &lt; tokens.length ;k++){ if(k==location){ _toString.append(":").append(" "); k=k+length-1; }else{ _toString.append(tokens[k]).append(" "); } } } return _toString.toString(); } public boolean equals(PatternGeneratorKey k) { if(this.tokens.length - this.length == k.tokens.length - k.length &amp;&amp; this.location == k.location){ //assume second one is larger String tokens[] = k.tokens; int length = k.length; int location = k.location; String [] tokens1 = this.tokens; int length1 = this.length; int location1 = this.location; //make the local variable point to the largest of the two if( this.tokens.length &gt; k.tokens.length){ tokens = this.tokens; length = this.length; location = this.location; tokens1 = k.tokens; length1 = k.length; location1 = k.location; } int i = 0 , j= 0; for(i = 0, j=0 ; i &lt; tokens.length;){ if(i == location ){ i = i + length; continue; } // if( j &gt;= location1 &amp;&amp; j&lt;= location1 + length1 -1){ if( j == location1){ j = j + length1; continue; } if(!tokens[i++].equalsIgnoreCase(tokens1[j++])){ return false; } } return true; }else{ return false; } } } </code></pre> <p>And, this is the code I am testing on</p> <pre><code>import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.hadoop.io.Text; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String value = "gm used cars"; // Compile all the words using regex String[] tokens = value.toString().split("\\s+"); //to find pattern we need atleast two words in the query if(tokens.length &lt;=1){ return; } Map&lt;PatternGeneratorKey,List&gt; map = new HashMap&lt;PatternGeneratorKey, List&gt;(); for(int l = 1 ; l &lt; tokens.length; l++){ for(int i = 0 ; i &lt; tokens.length - (l-1); i++){ String hit = new String(getPhrase(l, i, tokens)); PatternGeneratorKey key1 = new PatternGeneratorKey(i, l, tokens); List list = null; for(int k = 0;k&lt; tokens.length;k++){ System.out.println("i:" + i + ",l:" + l + ",tokens:" + tokens[k]); } System.out.println("hashcode:" + key1.hashCode()); if(!map.containsKey(key1)){ list = new ArrayList&lt;String&gt;(); map.put(key1, list); }else{ list = (List) map.get(key1); } list.add(hit); } } value = "ford used cars"; String[] tokens2= value.toString().split("\\s+"); PatternGeneratorKey key2 = new PatternGeneratorKey(0, 1, tokens); //run a sliding window for length 1 to tokens length -1 for(int l = 1 ; l &lt; tokens2.length; l++){ //genereate token pairs with sliding window. for(int i = 0 ; i &lt; tokens2.length - (l-1); i++){ //hit a single token or a + b if there are two. String hit = new String(getPhrase(l, i, tokens2)); PatternGeneratorKey key1 = new PatternGeneratorKey(i, l, tokens2); System.out.println(); System.out.println(key1.toString() + "|" + key2.toString() + "|"+ key1.equals(key2)); for(int k = 0;k&lt; tokens2.length;k++){ System.out.println("i:" + i + ",l:" + l + ",tokens:" + tokens2[k]); } System.out.println("hashcode:" + key1.hashCode()); List list = null; if(!map.containsKey(key1)){ list = new ArrayList&lt;String&gt;(); map.put(key1, list); }else{ list = (List) map.get(key1); } list.add(hit); } } value = "ford used cars"; tokens= value.toString().split("\\s+"); PatternGeneratorKey key1 = new PatternGeneratorKey(0,1,tokens); tokens2 = "gm used cars".split("\\s+"); key2 = new PatternGeneratorKey(0,1,tokens2); System.out.println(key1.equals(key2)); System.out.println(key2.equals(key1)); System.out.println(key1.hashCode() ); System.out.println(key2.hashCode() ); System.out.println(map); } private static String getPhrase(int l, int i, String[] tokens){ StringBuffer strin = new StringBuffer(); int index = 0; for(index = i ; index &lt; i+l;index++){ if(index &lt; i+l-1){ strin.append(tokens[index]).append("+"); } else { strin.append(tokens[index]); } } return strin.toString(); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload