Search code examples
javasortingtreemaptreeset

How to sort a TreeSet by Value?


I am pretty new to TreeMap and TreeSet and the likes and was wondering how to sort the data structures by value? I realise with a TreeSet you can sort it into alphabetical order automatically but I want it to order via value? Any idea on how to do this?

It currently prints like...

  • aaa: 29
  • aaahealthart: 30
  • ab: 23
  • abbey: 14
  • abdomin: 3
  • aberdeen: 29
  • aberdeenuni: 20

When I want it to print like...

  • aaahealthart: 30
  • aaa: 29
  • aberdeen: 29
  • ab: 23
  • aberdeenuni: 20
  • abbey: 14
  • abdomin: 3

Here is my method here...

ArrayList<String> fullBagOfWords = new ArrayList<String>();
public Map<String, Integer> frequencyOne;

public void termFrequency() throws FileNotFoundException{
    Collections.sort(fullBagOfWords);
    Set<String> unique = new TreeSet<String>(fullBagOfWords);
    PrintWriter pw = new PrintWriter(new FileOutputStream(frequencyFile));
    pw.println("Words in Tweets :   Frequency of Words");
    for (String key : unique) {
        int frequency = Collections.frequency(fullBagOfWords, key);

        System.out.println(key + ": " + frequency);
        pw.println(key + ": " + frequency);
        }
    pw.close();
    }

Thanks for all the help guys.


Solution

  • TreeMap orders by key, I don't think you can use the same implementation to sort by the value. But you can achieve the task with a slightly different approach:

    public Map<String, Integer> countWords(List<String> words) {
        Map<String, Integer> result = new Map<>();
        for (String word : words) {
            if (result.containsKey(word)) {
                // the word is already in the map, increment the count
                int count = result.get(word) + 1;
                result.put(word, count);
            } else {
                result.put(word, 1);
            }
        }
    
        return result;
    }
    

    Then you just need to sort the elements of the resulting map. You can do this in the following way:

    public List<Map.Entry<String, Integer> sortMap(Map<String, Integer> map) {
        List<Map.Entry<String, Integer> elements = new LinkedList<>(map.entrySet());
        Collections.sort(elements, new Comparator<Map.Entry<String, Integer>>() {
    
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 ) {
                return o1.getValue().compareTo(o2.getValue());
            }
    
        });
    }
    

    So you use the first method to count the word frequency and the second to sort by it.