Search code examples
javahashmaptreemaptreemaps

TreeMap getting exception "fromKey > toKey" (fromKey is greater than toKey?)


I've stored following xml attribute into

HashMap<String, String> extraParams = new HashMap<String, String>()

<parameter name="sourceAttrStart" value="true" />
<parameter name="user" value="admin" />
<parameter name="password" value="password" />
<parameter name="SQL" value="SELECT * FROM test.users" />
<parameter name="driverClass" value="com.mysql.jdbc.Driver" />
<parameter name="url" value="jdbc:mysql://tesco-db.ce7gg2eo7hdc.us-
<parameter name="sourceAttrEnd" value="true" />

Basically I want to get subset of hashmap between kets sourceAttrStart to sourceAttrEnd

This what I'm trying

TreeMap<String, String> sorted = new TreeMap<String, String>(extraParams);

SortedMap<String, String> sourceParams = sorted.subMap("sourceAttrStart", "sourceAttrEnd");

But getting below exception, any idea why?

java.lang.IllegalArgumentException: fromKey > toKey
    at java.util.TreeMap$NavigableSubMap.<init>(TreeMap.java:1368)
    at java.util.TreeMap$AscendingSubMap.<init>(TreeMap.java:1855)
    at java.util.TreeMap.subMap(TreeMap.java:913)
    at java.util.TreeMap.subMap(TreeMap.java:954)

Solution

  • TreeMap uses the natural order (compareTo() method) of keys to order the elements.
    The "sourceAttrEnd" String is before the "sourceAttrStart" String in terms of compareTo().
    Whereas the thrown exception as you invoke TreeMap.subMap("sourceAttrStart", "sourceAttrEnd") :

    java.lang.IllegalArgumentException: fromKey > toKey

    Whatever adding the elements in a HashMap and then using the HashMap object to create a sorted collection will not allow to make them ordered as you wish as HashMap doesn't guarantee the order of elements.
    So as alternative, you could add the elements in a LinkedHashMap as soon as the loading of the file as LinkedHashMap maintains the order of elements according to their insertion order.
    But the Properties class is not designed to keep the order of appearance of the elements. To allow that you should extend Properties.
    Here is an interesting example.

    Beyond the way to use, .properties files are not also designed to have a specific order of elements.
    So I think that a better alternative would be to use the Property class and get from it the entries you need. You could define entries keys in a List for example.

    Here is a basic example :

    Properties props = ...; // load your file
    List<String> keysToRetrieve = Arrays.asList("sourceAttrStart", "user", ..., "sourceAttrEnd");
    
    Map<String, String> entriesToRetrieve = new HashMap<>();
    for (String key : keysToRetrieve){
       entriesToRetrieve.put(key, props.getProperty(key)); 
    }