我知道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}}进行排序?
答案 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
,则会产生ClassCastException
。 TreeSet
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()。