1

I am trying to sort a map to show in a dropdown. But I am not able to get any sorting done. This will return a new map. But not with the map sorted by the key as I would expect.

private Map<String, String> mapInstrumentIDs = new TreeMap<>();

Map<Object, Object> val = mapInstrumentIDs
                    .entrySet()
                    .stream()
                    .sorted(Map.Entry.comparingByKey())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

I of course didn't think about that the key is actually an integer. This means sorting it as a string does not give me the expected result (as integer sort). Changing the key to Integer and converting the value will yield the expected result.

3
  • 6
    You don't need to sort mapInstrumentIDs. It's a TreeMap, so it implicitly sorts its entries by key. Commented Jul 27, 2015 at 11:23
  • 1
    can you paste your input and your expected output? Commented Jul 27, 2015 at 11:24
  • 1
    what makes you think that the map returned by .collect() is going to be sorted? Commented Jul 27, 2015 at 11:30

3 Answers 3

5

By default a TreeMap guarantees that its elements will be sorted in ascending key order.

Sign up to request clarification or add additional context in comments.

Comments

3

You should collect the results into a Map implementation that retains the order of its entries. LinkedHashMap will do:

Map<String, String> sorted = mapInstrumentIDs.entrySet().stream()
    .sorted(Map.Entry.comparingByKey())
    .collect(toMap(
            Map.Entry::getKey, 
            Map.Entry::getValue, 
            (x,y)-> {throw new AssertionError();},
            LinkedHashMap::new
    ));

3 Comments

Of course, if the intended order is being sorted by keys, a TreeMap will retain the order smoothly. Then we get, what the OP has before trying to sort the already sorted data…
I suspect this is a case of questioner not pasting the real code and he is not actually using a TreeMap or his TreeMap is using a Comparator other than natural ordering. Or maybe he wants to avoid O(log(n)) lookups of TreeMap.
Still, creating a map sorted by keys in natural order is as simple as new TreeMap<>(oldMap), insert a typecast to Map if oldMap happens to be a SortedMap having a different order (which I doubt). And yes, the question makes no sense…
0

Normally one would make a copy as:

private SortedMap<String, String> mapInstrumentIDs = new TreeMap<>();
SortedMap<String, String> val = new TreeMap(mapInstrumentIDs);

If you want a copy with key type Comparable<?> and value type Object, you want to specify the initial map as TreeMap and cannot use the standard collectors:

SortedMap<Comparable, Object> val = mapInstrumentIDs
                .entrySet()
                .collect(TreeMap<Comparable, Object>::new,
                    (m, e) -> { m.put(e.getKey(), e.getValue()); return m; },
                    (m, m2) -> m.addAll(m2)
                );

2 Comments

Don’t use reduce for mutable data structures! A TreeMap that you are going to modify is not an identity value. Use collect for a Mutable reduction
@Holger you are right; changed it, as that is FP pure.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.