使用 TreeSet 进行排序而不向其提供比较器

using TreeSet to sort without providing a Comparator to it

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

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

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

arraylist 中的第一个值,

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

hashmap 数组列表中的第二个值,

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

hashmap 数组列表中的第 3 个值,

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

现在,如果我想根据 mydate 键对 hashmap 的数组列表进行排序,我必须像这样在 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));
        }
    }); 

并且它会按排序顺序将数组列表存储在 TreeSet 中。但是我使用了自定义 Comparator 来实现这一点。如果我还为其提供自定义 Comparator,那么在这种情况下使用 TreeSet 对数据进行排序有什么意义?

如何根据 date 值对 HashMapArrayList 进行排序,而不使用 TreeSetComparator 的新实例?

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

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

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

你不能,直接。您可以编写一个 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> 并对其进行排序。

但是考虑到您必须提供与比较器基本相同的代码 and 将您与地图类型的比较绑定在一起,我觉得这样会更好只是为了坚持使用比较器。

如果您不向 TreeSet 提供 Comparator,那么它将依赖其元素 Comparable 来对它们进行排序。如果它们不是 Comparable,则会产生 ClassCastExceptionTreeSet javadocs 说明:

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.

HashMap class 不是 Comparable,因此您必须提供自定义 Comparator,以便 TreeSet 知道您希望如何对它们进行排序.您无法在没有 Comparator 的情况下对 HashMap 进行排序,无论它们是在 TreeSet 还是任何其他集合中。

在这种情况下使用 TreeSet 有很多好处。添加、查找和删除操作的复杂度为 O(log n)。如果为此使用 ArrayList,那么添加和删除操作将为 O(n),即使查找操作仍为 O(log n)。

来自 TreeSet javadoc 的更多内容:

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

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

不过,使用比较器是一种很好的做法,因为您将能够在运行时提供排序标准。

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