简体   繁体   中英

using TreeSet to sort without providing a Comparator to it

I know that TreeSet in java automatically sort its elements in ascending order an it guarantees the order.

for example, If i have an array of Date object in random and I copy it to TreeSet then it will be added in TreeSet in sorted way.

but suppose instead of a simple Date object, I have an ArrayList of HashMap<String,Object> , in the following format.

first value in arraylist,

{mydate = 32156464 , mystring = "abc", mystring2 = "xyz"}

2nd value in arraylist of hashmap,

{mydate = 64687678 , mystring = "abdc", mystring2 = "xyzzz"}

3rd value in arraylist of hashmap,

{mydate = 11233678 , mystring = "abxdc", mystring2 = "xyzppzz"}

Now if i want to sort this arraylist of hashmap based on mydate key, i have to create a new comparator in TreeSet instance like this,

public static Set<HashMap<String, Object>> mySet = new TreeSet<>(new Comparator<HashMap<String, Object>>() {
        @Override
        public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
            return ((Date) o2.get(mydate)).compareTo((mydate) o1.get(DATE));
        }
    }); 

and it will store the arraylist inside the TreeSet in sorted order just fine. But I have used a custom Comparator to achieve this. What is the point of using TreeSet in this situation for sorting data if i am also providing a custom Comparator to it ?

How can i sort this ArrayList of HashMap based on date value without using a new instance of Comparator in TreeSet ?

What is the point of using TreeSet in this situation for sorting data if i am also providing a custom Comparator to it ?

Because it's the TreeSet code that keeps it sorted. You haven't had to provide any of the code for that - all you've had to provide is the custom comparison.

How can i sort this ArrayList of HashMap based on date value without using a new instance of Comparator in TreeSet ?

You can't, directly. You could write a subclass of HashMap which implemented Comparable for itself, but that would seem a bit odd to me. For example:

public class SpecialMap extends HashMap<String, Object>
    implements Comparable<SpecialMap> {

    private final String key;

    public SpecialMap(String key) {
        this.key = key;
    }

    public int compareTo(SpecialMap other) {
        // TODO: Null handling
        Date thisDate = (Date) this.get(key);
        Date otherDate = (Date) other.get(key);
        return thisDate.compareTo(otherDate);
    }
}

Then you could have an ArrayList<SpecialMap> and sort that.

But given that you've had to provide basically the same code as for the comparator and bound your comparison with the map type, it feels to me like it would be better just to stick with the comparator.

If you don't supply a Comparator to the TreeSet , then it will rely on its elements being Comparable to sort them. If they're not Comparable , then a ClassCastException will result. The TreeSet javadocs explain:

A NavigableSet implementation based on a TreeMap. The elements are ordered using their natural ordering , or by a Comparator provided at set creation time, depending on which constructor is used.

But the HashMap class is not Comparable , so you must supply a custom Comparator so the TreeSet knows how you want to sort them. You cannot sort your HashMap s without a Comparator , whether they're in a TreeSet or any other collection.

There are advantages to using a TreeSet in this situation. The add, find, and remove operations are O(log n). If you were to use an ArrayList for this, then add and remove operations would be O(n), even if the find operation would still be O(log n).

More from TreeSet javadocs:

This implementation provides guaranteed log(n) time cost for the basic operations (add, remove and contains).

Instead of using HashMap you could create a class that contains mydate, mystring, mystring2 and implements a Comparable interface.

However it's a good practice to use comparator because you'll be able to supply sorting criteria in runtime.

The point of using a comparator in a TreeSet is that you don't have write the code to do the actual sorting, you just provide a method that determines which of your objects is first, based on your comparison rules. If you don't want to create a comparator, you would need to add to your collection objects that implement the Comparable interface. To sort an ArrayList, use Collections.sort().

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