1

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)
Swapnil Kotwal
  • 5,418
  • 6
  • 48
  • 92

2 Answers2

2

TreeMap sort keys in lexicographical order. String "sourceAttrEnd" is before "sourceAttrStart" in such order.

talex
  • 17,973
  • 3
  • 29
  • 66
  • 3
    To be accurate, TreeMap does NOT sort **keys** in lexicographical order. It sort keys in lexicographical order only when type of key is String, and without special comparator – Adrian Shum Apr 03 '18 at 09:52
2

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)); 
}
davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • actually It's `TestNG` xml values I retrived as `Map extraParams = context.getCurrentXmlTest().getSuite() .getParameters();`, I'm not sure will it maintain's the insertion order or not :( – Swapnil Kotwal Apr 03 '18 at 09:54
  • _"Whatever adding the elements in a HashMap and then using the HashMap object to create a sorted collection..."_ I think it is irrelevant of how the sorted map is created. It is simply OP's understanding on a sorted map is wrong. TreeMap does not sort by insertion order. – Adrian Shum Apr 03 '18 at 09:56
  • @Adrian Shum You are right and more generally relying on the order of elements in a ".properties" file is probably not the way to follow. – davidxxx Apr 03 '18 at 09:58
  • 1
    @Swapnil Kotwal I updated. I think trying to maintain the order is not the way. – davidxxx Apr 03 '18 at 09:59