Note that there are some explanatory texts on larger screens.

plurals
  1. POComparing TreeMap contents gives incorrect answer
    primarykey
    data
    text
    <p>I use a TreeMap as a 'key' inside another TreeMap</p> <p>ie</p> <pre><code>TreeMap&lt;TreeMap&lt;String, String&gt;, Object&gt; </code></pre> <p>In my code 'object' is a personal construct, but for this intance I have used a string.</p> <p>I have created a pair of TreeMaps to test the <code>TreeMap.CompareTo()</code> and <code>TreeMap.HashCode()</code> methods. this starts with the following...</p> <pre><code>public class TreeMapTest public void testTreeMap() { TreeMap&lt;String, String&gt; first = new TreeMap&lt;String, String&gt;(); TreeMap&lt;String, String&gt; second = new TreeMap&lt;String, String&gt;(); first.put("one", "une"); first.put("two", "deux"); first.put("three", "trois"); second.put("une", "one"); second.put("deux", "two"); second.put("trois", "three"); TreeMap&lt;TreeMap&lt;String, String&gt;, String&gt; english = new TreeMap&lt;TreeMap&lt;String, String&gt;, String&gt;(); TreeMap&lt;TreeMap&lt;String, String&gt;, String&gt; french = new TreeMap&lt;TreeMap&lt;String, String&gt;, String&gt;(); english.put(first, "english"); french.put(second, "french"); </code></pre> <p>From here I now call the the english item to see if it contains the key</p> <pre><code>if (english.containsKey(second)) { System.out.println("english contains the key"); //throws error of ClassCastException: Java.util.TreeMap cannot be cast to //Java.Lang.Comparable, reading the docs suggests this is the feature if the key is //not of a supported type. //this error does not occur if I use a HashMap structure for all maps, why is //this key type supported for one map structure but not another? } </code></pre> <p>However I should note that both HashMap and TreeMap point to the same HashCode() method in the AbstractMap parent.</p> <p>My first thought was to convert my TreeMap to a HashMap, but this seemed a bit soppy! So I decided to apply the hashCode() method to the 2 treemap objects.</p> <pre><code>int hc1 = first.hashCode(); int hc2 = second.hashCode(); if(hc1 == hc2) { systom.out.printline("values are equal " + hc1 + " " + hc2); } </code></pre> <p>prints the following</p> <pre><code>values are equal 3877431 &amp; 3877431 </code></pre> <p>For me the hashcode should be different as the key values are different, I can't find details on the implementation difference of the hashCode() method between HashMap and TreeMap.</p> <p>Please not the following. changing the Keys only to HashMap doesn't stop the ClassCastException error. Changing all the maps to a HashMap does. so there is something with the containsKey() method in TreeMap that isn't working properly, or I have missunderstood - can anyone explain what?</p> <p>The section where I get the hashCode of the first and second map objects always produces the same output (no matter if I use a Hash or Tree map here) However the if(english.ContainsKey(second)) doesn't print any message when HashMaps are used, so there is obviously something in the HashMap implementation that is different for the compareTo() method.</p> <p>My principle questions are.</p> <p>Where can I find details of the types of keys for use in TreeMap objects (to prevent future 'ClassCastException' errors).</p> <p>If I can't use a certain type of object as a key, why am I allowed to insert it as a key into the TreeMap in the first place? (surely if I can insert it I should be able to check if the key exists?)</p> <p>Can anyone suggest another construct that has ordered inster / retrieval to replace my TreeMap key objects?</p> <p>Or have I potentially found strange behaviour. From my understanding I should be able to do a drop in replacement of TreeMap for HashMap, or have I stumbled upon a fringe scenario?</p> <p>Thanks in advance for your comments.</p> <p>David.</p> <p>ps. the problem isn't a problem in my code as I use a personal utility to create a hash that becomes dependent on the Key and Value pairs (ie I calculate key hash values differently to value hash values... sorry that if is a confusing sentence!) I assume that the hashCode method just sums all the values together without considering if a item is a key or a value.</p> <p>pps. I'm not sure if this is a good question or not, any pointers on how to improve it?</p> <p>Edit.</p> <p>from the responses people seem to think I'm doing some sort of fancy language dictionary stuff, not a surprise from my example, so sorry for that. I used this as an example as it came easily to my brain, was quick to write and demonstrated my question.</p> <p>The real problem is as follows.</p> <p>I'm accessing a legacy DB structure, and it doesn't talk nicely to anything (result sets aren't forward and reverse readable etc). So I grab the data and create objects from them. The smallest object represents a single row in a table (this is the object that in the above example I have used a string value 'english' or 'french' for.</p> <p>I have a collection of these rowObjects, each row has an obvious key (this is the TreeMap that points to the related rowObject).</p> <p>i don't know if that makes things any clearer!</p> <p>Edit 2.</p> <p>I feel I need to elaborate a little further as to my choice of originaly using </p> <pre><code>hashMap&lt;HashMap&lt;String,string&gt;, dataObject&gt; </code></pre> <p>for my data structure, then converting to TreeMap to gain an ordered view.</p> <p>In edit 1 I said that the legacy DB doesn't play nicely (this is an issue with the JDBC.ODBC I suspect, and I'm not about to acquire a JDBC to communicate with the DB). The truth is I apply some modifications to the data as as I create my java 'dataObject'. This means that although the DB may spit out the results in ascending or descending order, I have no way of knowing what order they are inserted into my dataObject. Using a likedHashMap seems like a nice solution (see duffymo's suggestion) but I later need to extract the data in an ordered fashion, not just consecutively (LinkedHashMap only preserves insertion order), and I'm not inclined to mess around with ordering everything and making copies when I need to insert a new item in between 2 others, TreMap would do this for me... but if I create a specific object for the key it will simply contain a TreeMap as a member, and obviously I will then need to supply a compareTo and hashCode method. So why not just extent TreeMap (allthough Duffymo has a point about throwing that solution out)!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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