使用 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
值对 HashMap
的 ArrayList
进行排序,而不使用 TreeSet
中 Comparator
的新实例?
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
,则会产生 ClassCastException
。 TreeSet
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().
我知道 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
值对 HashMap
的 ArrayList
进行排序,而不使用 TreeSet
中 Comparator
的新实例?
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
,则会产生 ClassCastException
。 TreeSet
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().