Java TreeMap Comparator
Asked Answered
D

3

37

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
Dunford answered 18/10, 2012 at 4:23 Comment(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; } ```Thumbsdown
T
73

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]
Tiu answered 18/10, 2012 at 4:30 Comment(5)
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));Dunford
@Dunford 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.Tiu
This works but it removes duplicate values. But i want to keep duplicate values in the list. Can anyone help me?Floriated
..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.Sickly
@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 leetcodeNemertean
A
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());
        }
    });
Angloindian answered 18/10, 2012 at 4:27 Comment(1)
@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.Angloindian
P
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());
Pruitt answered 22/8, 2017 at 22:20 Comment(1)
This is trying to solve the last question, but not the first two.Bilabial

© 2022 - 2024 — McMap. All rights reserved.