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

时间:2015-02-02 19:08:35

标签: java sorting arraylist

我知道java中的TreeSet会按升序自动对其元素进行排序,以保证顺序。

例如,如果我有一个随机的Date对象数组,我将其复制到TreeSet,那么它将以TreeSet方式排序。

但是假设我有一个Date ArrayList而不是一个简单的HashMap<String,Object>对象,格式如下。

arraylist中的第一个值,

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

hashmap的arraylist中的第二个值,

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

hashmap的arraylist中的第3个值,

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

现在,如果我想根据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));
        }
    }); 

它会将排序列表中的arraylist以排序顺序存储在TreeSet内。但我使用自定义Comparator来实现这一目标。如果我还提供自定义TreeSet,那么在这种情况下使用Comparator对数据进行排序有什么意义呢?

如何在不使用ArrayList中的HashMap新实例的情况下,根据date值对Comparator TreeSet {{1}}进行排序?

4 个答案:

答案 0 :(得分:4)

  

如果我还为其提供自定义Comparator,在这种情况下使用TreeSet对数据进行排序有什么意义呢?

因为它是保持排序的TreeSet代码。您没有必须提供任何代码 - 所有您必须提供的是自定义比较。

  

如何在不使用TreeSet中新的Comparator实例的情况下,根据日期值对HashMap的ArrayList进行排序?

你不能,直接。您可以编写HashMap的子类,为自己实现Comparable,但这对我来说似乎有些奇怪。例如:

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);
    }
}

然后你可以拥有ArrayList<SpecialMap>并对其进行排序。

但鉴于你必须提供与比较器基本相同的代码和与地图类型的比较,我觉得最好坚持使用比较器。

答案 1 :(得分:1)

如果您未向Comparator提供TreeSet,则会依赖其Comparable元素对其进行排序。如果它们不是Comparable,则会产生ClassCastExceptionTreeSet javadocs解释:

  

基于TreeMap的NavigableSet实现。元素按照natural ordering或在创建时设置的Comparator进行排序,具体取决于使用的构造函数。

HashMap课程不是Comparable,因此您必须提供自定义Comparator,以便TreeSet了解您希望如何对其进行排序。如果没有HashMap,您无法对Comparator进行排序,无论它们是TreeSet还是其他任何集合。

在这种情况下使用TreeSet是有好处的。添加,查找和删除操作是O(log n)。如果您为此使用ArrayList,则添加和删除操作将为O(n),即使查找操作仍为O(log n)。

来自TreeSet javadocs的更多内容:

  

此实现为基本操作(添加,删除和包含)提供了有保证的log(n)时间成本。

答案 2 :(得分:1)

您可以创建一个包含mydate,mystring,mystring2并实现Comparable接口的类,而不是使用HashMap。

然而,使用比较器是一个好习惯,因为您将能够在运行时提供排序标准。

答案 3 :(得分:1)

在TreeSet中使用比较器的关键是你没有编写代码来进行实际排序,你只需提供一种方法,根据比较规则确定哪个对象是第一个。 如果您不想创建比较器,则需要添加实现Comparable接口的集合对象。 要对ArrayList进行排序,请使用Collections.sort()。