23

In my assignment we are read from a file the text:

To be, or not to be: that is the question:
Whether 'tis nobler in the mind to suffer

then count the times each has occured. I've been able to print this map unsorted, then I was able to make a TreeMap and print it in natural order (which is shown below). I don't know how to print in reverse order. I know a way to use a comparator, but I'm a little rusty so I've done what I can. Furthermore, I don't know how to set the comparator up to sort the Treemap into reverse order.

Here's my method to print Unsorted and Naturally sorted:

private static void sortPrintFrequencies(Map<String,Integer> vocabulary, PrintStream                                                  output {
Iterator iterator = vocabulary.keySet().iterator();
System.out.println("Unsorted");

while (iterator.hasNext()) {
 String key = iterator.next().toString();
 String value = vocabulary.get(key).toString();
 String times = "times.";
 String appears = "appears";

System.out.printf("%35s", key + "    " + appears + "    " + value + " "+ times);
System.out.println();
    }
System.out.println("========================================");
System.out.println("SORTED NATURALLY BY KEY");
TreeMap newVocabulary = new TreeMap(vocabulary);
Iterator iterator2 = newVocabulary.keySet().iterator();
while (iterator2.hasNext()) {
  String key = iterator2.next().toString();
  String value = newVocabulary.get(key).toString();
  String times = "times.";
  String appears = "appears";

    System.out.printf("%35s", key + "    " + appears + "    " + value + " "+ times);
    System.out.println();
}
  TreeMap revVocabulary = new TreeMap(new RevCmpKey());

  System.out.println("========================================");

}

Here's my comparator:

import java.util.*;
public class RevCmpKey implements Comparator<String> {
public int compare(String e1, String e2) {
    //compareTo in String classs
    if(e1.compareTo(e2) <1)return -1;
    if(e1.compareTo(e2) >1)return 1;
    return 0;
}
}
Dávid Horváth
  • 4,050
  • 1
  • 20
  • 34
IC2D
  • 471
  • 4
  • 11
  • 22
  • So is your question how to set up a comparator? – simchona Feb 18 '12 at 03:20
  • no, actually I was hoping for someone to not only help me with my comparator, but to use to sort the TreeMap. Thanks! – IC2D Feb 18 '12 at 03:22
  • I think you should show some more effort then. This seems a bit too "give me teh codez" at the moment. Maybe show what you think the comparator should look like, besides the skeleton you have? – simchona Feb 18 '12 at 03:23
  • oops!! that's my old comparator code!! ill change it. Thanks for pointing it out :) – IC2D Feb 18 '12 at 03:37

5 Answers5

64

What about copying your Map into a new one naturally reverse ordered?

new TreeMap<String,Integer>(Collections.reverseOrder())
Olivier C
  • 1,151
  • 10
  • 11
  • 3
    `descendingMap` is probably faster (see other answer about this), since it doesn't require copying the entire collection. – Luke Hutchison Sep 13 '20 at 06:16
19

Short Answer:

Use descendingKeySet or descendingMap.

Long Answer:

Solution 1:

As Oliver correctly mentioned, you can copy the map into a new TreeMap to reach your goal.

However, when using descendingKeySet, you won't need to create a new TreeMap:

treeMap.descendingKeySet()

Here's an example:

private static void printReverseTreeMap(TreeMap<String,Integer> treeMap){
    for(String key : treeMap.descendingKeySet()){
        System.out.println("value of " + key + " is " + treeMap.get(key));
    }
}

Solution 2:

You can also create a new Map in reverse order using descendingMap as well as Collections.reverseOrder():

NavigableMap<String, Integer> reveresedTreeMap = treeMap.descendingMap();

Note that descendingMap returns NavigableMap.

Positive Navid
  • 2,481
  • 2
  • 27
  • 41
  • 2
    `NavigableMap.descendingMap()` is probably faster than `Collections.reverseOrder()`, and also probably requires less memory, since a descending map is just a reversed view of the underlying map. – Luke Hutchison Sep 12 '20 at 08:00
  • What's the time complexity (big O) of map.descendingMap()? Can we use this to iterate over the k greatest keys in O(k) time? – PlsWork Nov 25 '20 at 15:54
1

Here you can also prepare a ReverseComparator and use for any class, used in Ordered-Collection :

class ReverseComparator implements Comparator<Comparable<Object>> {

    @Override
    public int compare(Comparable<Object> o1, Comparable<Object> o2) {

        return o2.compareTo( o1 );
    }

}

As usually we compare o1 with o2, but for reverse compare o2 with o1

Devarsh
  • 116
  • 3
1

Just try below

private TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> getCpnHistoryMap(
        List<TicketingDocumentHistory> tktHistoryList,List<TicketingDocumentServiceCouponTicket> couponList){

    TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> cpnHistoryMap = new TreeMap<>(Collections.reverseOrder());
    cpnHistoryMap.put(BigInteger.valueOf(Integer.MAX_VALUE), getOcCpnHistoryList(couponList));
    tktHistoryList
            .stream()
            .filter(history -> history.getCode().equals(RVL))
            .forEach(history -> cpnHistoryMap.put(history.getSequence(), getCpnHistoryList(cpnHistoryMap, history)));

    TreeMap<BigInteger, List<TicketingDocumentServiceCouponHistory>> cpnHistMapInOrder =  new TreeMap<>();
    cpnHistMapInOrder.putAll(cpnHistoryMap);
    return cpnHistMapInOrder;
}
atul sachan
  • 597
  • 5
  • 10
1

Since String is already comparable, the inverse Comparator is trivial:

public class RevCmpKey implements Comparator<String> {

  public int compare(String e1, String e2) {
    return - e1.compareTo(e2);
  }
}

The other problem is that you are not specifying the values for the Generics; When you construct the TreeMap, you should use

TreeMap<String, Integer> revVocabulary = new TreeMap<String, Integer>(new RevCmpKey());

Then you just call putAll and that is enough

Luis
  • 1,294
  • 7
  • 9