0

I have a Map which I am simplifying but in essense contains key values of some data such as:

Yahya, 4 
John, 4
Blake, 2
Jill 2
Janoe, 6
Jilly 12
Zapon, 5
Zoe, 4
Hamed, 1

I need to order this so that I get the following output:

1. Jilly, 12 pts
2. Janoe, 6 pts
3. Zapon, 5 pts
4. John, 4 pts
4. Yahya, 4 pts
4. Zoe, 4 pts
7. Blake, 2 pts
7. Jill, 2 pts
9. Hamed, 1 pts

I have already used a comparator to order the Map values according to value:

public <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

and read : How to get element position from Java Map, Order HashMap alphabetically by value and much more but not sure how to put it together.

I know you can use this to get key values:

for (Map.Entry<String, Integer> entry : map.entrySet()){
    System.out.println(entry.getKey() + " ," + entry.getValue() + " pts"); 
}

However two functionalities missing:

  1. Sort alphabetically when keys are the same
  2. Keep same numbering when the value is the same and jump to correct count afterwards.

Tried this:

Map<String, Integer> map = sortByValues(groupList);
            int count = 1;
            int counter = 1;
            int previousScore = 0;

            for (Map.Entry<String, Integer> entry : map.entrySet()) {

               //counter = count;
                if (previousScore == entry.getValue()) {

                    System.out.println(counter - 1 + " " + entry.getKey() + "," + entry.getValue() + " pts");

                } else {

                    System.out.println(counter + " " + entry.getKey() + "," + entry.getValue() + " pts");
                    previousScore = entry.getValue();
                    count++;
                }
                counter++;

            }

Any thoughts are appreciated and welcome. Can anybody suggest a method to achieve the required result ?

Community
  • 1
  • 1
Afshin Ghazi
  • 2,784
  • 4
  • 23
  • 37

2 Answers2

0
  1. In your ValueComparator replace if (compare == 0) return 1; with if(compare == 0) return k1.compareTo(k2).
  2. When generating the "numbering" (you have not shown any code for it), keep two counts. Increase one of them on every iteration, and assign it to the other one, but only if current value is different from the last one. Use the latter to generate the "numbering".
Dima
  • 39,570
  • 6
  • 44
  • 70
  • Thanks for the answer but...k1.compareTo(k2) is removes the duplicate value instead of numbering and tried various counts before and hence asking the question as I couldn't get it right. Had the same idea but don't know how to implement. – Afshin Ghazi Jan 16 '16 at 04:35
  • Declare `K` as `Comparable` too, same way you did with `V`. Or, better yet, get rid of the generic, and just use `Map`, since that's what you really need. Show your code for the counts if you want us to help you figure out what's wrong with it. – Dima Jan 16 '16 at 04:38
0

This is what I ended up with to make it work to have correct counter:

Map <String, Integer>map = sortByValues(leagueTable);

            int counter = 1;
            int previousScore = 0;
            int relativeCount = 0;
            int n= 0;
            for (Map.Entry<String, Integer> entry : map.entrySet())
            {

               int value = entry.getValue();


               if(previousScore == entry.getValue()){

                   if(n == 0){

                      relativeCount = counter-1;  

                   n++;
                   }
               System.out.println(relativeCount + " " + entry.getKey() + "," + entry.getValue() + " pts");

               }
               else{
               n=0;
               System.out.println(counter + " " + entry.getKey() + "," + entry.getValue() + " pts");
                previousScore = entry.getValue();

               } 
               counter++;

            }
Afshin Ghazi
  • 2,784
  • 4
  • 23
  • 37