简体   繁体   English

使用TreeSet进行排序而不向其提供Comparator

[英]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. 我知道java中的TreeSet按升序自动对其元素进行排序,以保证顺序。

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. 例如,如果我有一个随机的Date对象数组,并将其复制到TreeSet那么它将以有序的方式添加到TreeSet中。

but suppose instead of a simple Date object, I have an ArrayList of HashMap<String,Object> , in the following format. 但是假设我有一个HashMap<String,Object>ArrayList ,而不是一个简单的Date对象,格式如下。

first value in arraylist, arraylist的第一个价值,

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

2nd value in arraylist of hashmap, hashmap的arraylist中的第二个值,

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

3rd value in arraylist of hashmap, hashmap的arraylist中的第3个值,

{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, 现在,如果我想基于mydate键对这个hashmap的arraylist进行排序,我必须在TreeSet实例中创建一个新的比较器,如下所示,

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. 并且它会按照排序顺序将arraylist存储在TreeSet中。 But I have used a custom Comparator to achieve this. 但我使用自定义Comparator来实现这一目标。 What is the point of using TreeSet in this situation for sorting data if i am also providing a custom Comparator to it ? 如果我还在为它提供自定义Comparator ,那么在这种情况下使用TreeSet对数据进行排序有什么意义呢?

How can i sort this ArrayList of HashMap based on date value without using a new instance of Comparator in TreeSet ? 如何在不使用TreeSetComparator新实例的情况下,根据date值对HashMapArrayList进行排序?

What is the point of using TreeSet in this situation for sorting data if i am also providing a custom Comparator to it ? 如果我还在为它提供自定义Comparator,那么在这种情况下使用TreeSet对数据进行排序有什么意义呢?

Because it's the TreeSet code that keeps it sorted. 因为它是TreeSet代码,它保持排序。 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 ? 如何在不使用TreeSet中的Comparator新实例的情况下,根据日期值对HashMap的ArrayList进行排序?

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. 你可以写一个HashMap的子类,它为自己实现了Comparable ,但这对我来说似乎有些奇怪。 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. 然后你可以有一个ArrayList<SpecialMap>并对其进行排序。

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. 如果你没有向TreeSet提供Comparator ,那么它将依赖它的元素Comparable来对它们进行排序。 If they're not Comparable , then a ClassCastException will result. 如果它们不是Comparable ,那么将导致ClassCastException The TreeSet javadocs explain: TreeSet javadocs解释:

A NavigableSet implementation based on a TreeMap. 基于TreeMap的NavigableSet实现。 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. 但是HashMap类不是Comparable ,因此您必须提供自定义Comparator以便TreeSet知道您希望如何对它们进行排序。 You cannot sort your HashMap s without a Comparator , whether they're in a TreeSet or any other collection. 如果没有Comparator ,您无法对HashMap排序,无论它们是在TreeSet还是在任何其他集合中。

There are advantages to using a TreeSet in this situation. 在这种情况下使用TreeSet有一些优点。 The add, find, and remove operations are O(log n). 添加,查找和删除操作是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). 如果您为此使用ArrayList ,则添加和删除操作将为O(n),即使查找操作仍为O(log n)。

More from TreeSet javadocs: 更多来自TreeSet javadocs:

This implementation provides guaranteed log(n) time cost for the basic operations (add, remove and contains). 此实现为基本操作(添加,删除和包含)提供了有保证的log(n)时间成本。

Instead of using HashMap you could create a class that contains mydate, mystring, mystring2 and implements a Comparable interface. 您可以创建一个包含mydate,mystring,mystring2并实现Comparable接口的类,而不是使用HashMap。

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. 在TreeSet中使用比较器的关键是你没有编写代码来进行实际排序,你只需提供一种方法,根据比较规则确定哪个对象是第一个。 If you don't want to create a comparator, you would need to add to your collection objects that implement the Comparable interface. 如果您不想创建比较器,则需要添加实现Comparable接口的集合对象。 To sort an ArrayList, use Collections.sort(). 要对ArrayList进行排序,请使用Collections.sort()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM