38

I need a comparator for a TreeMap. Should I write this anonymously in the constructor for my TreeMap? How else could I write my comparator. Currently, Java does not like my code (can I do this anonymously?):

SortedMap<String, Double> myMap = 
    new TreeMap<String, Double>(new Comparator<Entry<String, Double>>()
    {
        public int compare(Entry<String, Double> o1, Entry<String, Double> o2)
        {
            return o1.getValue().compareTo(o2.getValue());
        } 
    });
  1. Can I do the above anonymously?
  2. How else could I do this?
  3. I want to sort myMap by the Value not the Key
1
  • The TreeMap comparator signature is on the key only. For example: ``` new Comparator<String>() { @Override public int compare(String a, String b) { return 0; } ``` Commented Jul 1, 2021 at 17:08

3 Answers 3

75

You can not sort TreeMap on values.

A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used You will need to provide comparator for Comparator<? super K> so your comparator should compare on keys.

To provide sort on values you will need SortedSet. Use

SortedSet<Map.Entry<String, Double>> sortedset = new TreeSet<Map.Entry<String, Double>>(
            new Comparator<Map.Entry<String, Double>>() {
                @Override
                public int compare(Map.Entry<String, Double> e1,
                        Map.Entry<String, Double> e2) {
                    return e1.getValue().compareTo(e2.getValue());
                }
            });

  sortedset.addAll(myMap.entrySet());

To give you an example

    SortedMap<String, Double> myMap = new TreeMap<String, Double>();
    myMap.put("a", 10.0);
    myMap.put("b", 9.0);
    myMap.put("c", 11.0);
    myMap.put("d", 2.0);
    sortedset.addAll(myMap.entrySet());
    System.out.println(sortedset);

Output:

  [d=2.0, b=9.0, a=10.0, c=11.0]
Sign up to request clarification or add additional context in comments.

5 Comments

How do I add an element one at a time to myMap? myMap.add(Map.Entry<String, Double> new Map.Entry<String, Double>(vStr, cur));
@CodeKingPlusPlus No. you use put method only Check the example that is added. You put values to Map once your are done use SortedSet to sort values.
This works but it removes duplicate values. But i want to keep duplicate values in the list. Can anyone help me?
..or "even you take elements and order them, when you put them back into a TreeMap, the order is still decided by the key comparator/natural order". Instead, you can insert the ordered entries into a LinkedHashmap to at least return an ordered map view of elements.
@PriyankaAlachiya Use an ArrayList instead of a set. Add the elements of the map to the list and pass in the comparator in Collections.sort(). Worked for me. Also I used technique when solving "Top K Frequent Elements" on leetcode
18

The comparator should be only for the key, not for the whole entry. It sorts the entries based on the keys.

You should change it to something as follows

SortedMap<String, Double> myMap = 
    new TreeMap<String, Double>(new Comparator<String>()
    {
        public int compare(String o1, String o2)
        {
            return o1.compareTo(o2);
        } 
});

Update

You can do something as follows (create a list of entries in the map and sort the list base on value, but note this not going to sort the map itself) -

List<Map.Entry<String, Double>> entryList = new ArrayList<Map.Entry<String, Double>>(myMap.entrySet());
    Collections.sort(entryList, new Comparator<Map.Entry<String, Double>>() {
        @Override
        public int compare(Entry<String, Double> o1, Entry<String, Double> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    });

1 Comment

@CodeKingPlusPlus: You cannot sort the map itself based on values. But you can get list of entries and sort it. But then it might not make sense to have a TreeMap, unless you switch the key and value.
0

you can swipe the key and the value. For example

        String[] k = {"Elena", "Thomas", "Hamilton", "Suzie", "Phil"};
        int[] v = {341, 273, 278, 329, 445};
        TreeMap<Integer,String>a=new TreeMap();
        for (int i = 0; i < k.length; i++) 
           a.put(v[i],k[i]);            
        System.out.println(a.firstEntry().getValue()+"\t"+a.firstEntry().getKey());
        a.remove(a.firstEntry().getKey());
        System.out.println(a.firstEntry().getValue()+"\t"+a.firstEntry().getKey());

1 Comment

This is trying to solve the last question, but not the first two.

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.