简体   繁体   中英

How to sort java sort map by values with the compare method already in class?

I want to sort a map by its values. But the compare method is already in the class.

public class Parser implements Comparator<String> {

    private Map<String, Integer> frequencies;

    public Parser() {
        frequencies = new HashMap<String, Integer>();
    }


    public int getCount(String word) {
        Integer c = frequencies.get(word);
        if (c == null) {
            return 0;
        }
        else {
            return c.intValue();
        }
    }


    public int compare(String o1, String o2) {
        int count1 = getCount(o1);
        int count2 = getCount(o2);
        return count1 < count2 ? -1 : count1 > count2 ? 1 : 0;
    }

    public List<String> getWordsInOrderOfFrequency(){
        TreeMap<String,Integer> sorted_map = new TreeMap<String,Integer>();
        sorted_map.putAll(frequencies);
        ArrayList<String> result = new ArrayList<String>(sorted_map.keySet());
        return result;
        }
}

Here the question is in the getWordsInOrderOfFrequenct() method. I want to sort the keyset by its values after compared.

Here is the code snippet you can observe how I achieved that

  public class WordFrequency {
        public static String sentence = "one three two two three three four four four";
        public static Map<String, Integer> map;

        public static void main(String[] args) {
            map = new HashMap<>();
            String[] words = sentence.split("\\s");

            for (String word : words) {
                Integer count = map.get(word);
                if (count == null) {
                    count = 1;
                } else {
                    ++count;
                }
                map.put(word, count);
            }

            Comparator<String> myComparator = new Comparator<String>() {

                @Override
                public int compare(String s1, String s2) {
                    if (map.get(s1) < map.get(s2)) {
                        return -1;
                    } else if (map.get(s1) > map.get(s2)) {
                        return 1;
                    } else {
                        return s1.compareTo(s2);
                    }
                }

            };
            SortedMap<String, Integer> sortedMap = new TreeMap<String, Integer>(myComparator);
            System.out.println("Before sorting: " + map);
            sortedMap.putAll(map);
            System.out.println("After Sorting based on value:" + sortedMap);

        }
    }

I think the trick is to extract the behaviour of your compare method so it can be reused in the sort...

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.google.common.collect.Lists.*;

public class Parser implements Comparator<String> {

    private Map<String, Integer> frequencies = new HashMap<String, Integer>();

    public int getCount(String word) {
        Integer c = this.frequencies.get(word);
        if (c == null) {
            return 0;
        }
        else {
            return c.intValue();
        }
    }

    public int compare(String o1, String o2) {
        return staticCompare(getCount(o1), getCount(o2));
    }

    private static int staticCompare(int count1, int count2) {
        return count1 < count2 ? -1 : count1 > count2 ? 1 : 0;
    }

    public List<String> getWordsInOrderOfFrequency(){
        List<Map.Entry<String, Integer>> entries = newArrayList(frequencies.entrySet());
        Collections.sort(entries, (o1, o2) -> staticCompare(getCount(o1.getKey()), getCount(o2.getKey())));
        return entries.stream().map(entry -> entry.getKey()).collect(Collectors.toList());
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM