1

Learning Java as I go (Python background). Simple word count program in Java 7 code (can not use J8!).

I have a hash map of word:count pairs. Now I need to sort on count (decreasing order), and break ties with using word in alphabetical order.

Have read s/o and I tried a treemap but it does not seem to handle ties very well so I don't think that is right.

I have seen a lot of solutions posted that define a new class sortbyvalue and define a comparator. These will not work for me as I need to keep the solution all contained in the existing class.

I am looking for feedback on this idea:

  • iterate over the map entries (me) in the hashmap
  • use me.getKey = K and me.getValue = V
  • new Map.Entry reverse_me = (V,K) {not sure about this syntax}
  • add reverse_me to a List
  • repeat for all me in map
  • List.sort { this is where I am unsure, on how this will sort and no idea how to write a comparator. At this point each List element would be a (count, word) pair and the sort() should sort by count in decreasing and then by word in case of same counts in alphabetical order)

This would be the final output.

Is this a logical progression? I can tell from the many posts that there are many opinions on how to do this, but this is the one I can wrap my head around.

Also, can not use Guava.

2
  • 5
    TreeMap handles ties perfectly (but the sorting happens on the key, not the value of course, use TreeSet for value ordering), the fault was most likely with your code. HashMap on the other hand cannot hold an order (except LinkedHashMap, but even that's not sortable). Commented Sep 10, 2015 at 8:10
  • 1
    First thing first, in java, you will need to learn about Collections.sort(...), Comparator and Comparable. You will need that knowledge for solving your problem. Commented Sep 10, 2015 at 8:17

2 Answers 2

3

You can create an List of Entry set from the map. Sort the List using Collections.sort(). You can pass the custom Comparator for sorting by Key when Value(s) are same.

Set<Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
{
  public int compare( Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 )
  {
    int result = (o2.getValue()).compareTo( o1.getValue() );
    if (result != 0) {
      return result;
    } else {
      return o1.getKey().compareTo(o2.getKey());
    }
  }
} );
Sign up to request clarification or add additional context in comments.

2 Comments

@fabian Updated the example. Thanks.
I used this and it worked in my application. Besides being first answer I think it's a very intuitive solution for a coder with Python, not Java, background. thx
1

This collection reflects the correct order only as long as the map entries are not changed

        HashMap<String, Integer> map = new HashMap<>();
        TreeSet<Map.Entry<String, Integer>> entriesSet = new TreeSet<>(new Comparator<Map.Entry<String, Integer>>(){
            @Override
            public int compare(Map.Entry<String, Integer> me1, Map.Entry<String, Integer> me2) {
                return me1.getValue().compareTo(me2.getValue());  
            }
        });
        entriesSet.addAll(map.entrySet());

1 Comment

I already used this accepted answer mostly because it came across first. I do like this TreeSet solution though, it looks very straightforward. As I learn more Java I hope to understand this.

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.