正确排序集合中的相等项目
Properly sort equal items in Collection
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Collections.sort(gpsDtoList, new Comparator<T>() {
public int compare(T o1, T o2) {
return -o1.getEreigniszeit().compareTo(o2.getEreigniszeit());
}
});
知道这个事实,我怎么能用符号表示这些项目确实相等,即使列表中有一个 "higher"(隐含的意思是更年轻 timestamp
)
测试数据
假设o2.Ereigniszeit = 0000
和o2.Ereigniszeit = 0000
(这只是一个非常简单和抽象的例子)
症结所在
我稍后会处理这些数据并使用此逻辑在 Leaflet 地图上突出显示最新的 (green)
和最旧的 (red)
对象
if (i == 0) {
properties.put("markerStyle", LATEST);
} else if (i == gpsDtoList.size() - 1) {
properties.put("markerStyle", OLDEST);
}
然而字面意思是equal
,我该如何正确处理呢?
(我正在处理很多 gps 位置,所以任何 O(N^2)
都是不可接受的。)
返回对象为GpsDTO
public class GpsDTO implements Serializable {
....
public Date getEreigniszeit() {
return ereigniszeit;
}
public void setEreigniszeit(Date ereigniszeit) {
this.ereigniszeit = ereigniszeit;
}
我建议你使用NavigableMap
;这些按键排序。
// entries will be sorted by your comparator
NavigableMap<Date, List<GpsDTO>> map = new TreeMap<yourComparator>();
// if there is a list already, it will be used; otherwise, a new one will be created
gpsDtoList.forEach(dto ->
map.computeIfAbsent(dto.getEreigniszeit(), new ArrayList<>())
.add(dto));
// iterate the relevant lists to set the respective markers
map.firstEntry().forEach(dto -> dto.setOldest());
if (map.size() > 1) {
map.lastEntry().forEach(dto -> dto.setNeweset());
}
这里没有 lambda 表达式:
NavigableMap<Date, List<GpsDTO>> map = new TreeMap<yourComparator>();
for (GpsDTO dto : gpsDtoList) {
List<GpsDTO> list = map.computeIfAbsent(dto.getEreigniszeit());
list.add(dto);
}
for (GpsDTO firstDto : map.firstEntry()) {
setOldestProperty(firstDto);
}
if (map.size() > 1) {
for (GpsDTO lastDto : map.lastEntry()) {
setNewestProperty(lastDto);
}
}
解决方案
首先我确定最新和最旧的日期。
Date youngestDate = null;
Date oldestDate = null;
Collections.sort(gpsDtoList, new Comparator<T>() {
public int compare(T o1, T o2) {
return -o1.getEreigniszeit().compareTo(o2.getEreigniszeit());
}
});
if (gpsDtoList != null && gpsDtoList.size() > 1) {
youngestDate = gpsDtoList.get(0).getEreigniszeit();
oldestDate = gpsDtoList.get(gpsDtoList.size() - 1).getEreigniszeit();
}
和实际设置逻辑
if (youngestDate != null && oldestDate != null) {
if (i == 0 || youngestDate.equals(gpsDtoList.get(i).getEreigniszeit())) {
properties.put("markerStyle", LATEST);
} else if (oldestDate.equals(gpsDtoList.get(i).getEreigniszeit())) {
properties.put("markerStyle", OLDEST);
}
}
测试用例/解释
#1 o1,o2
等于?
youngestDate
和 oldestDate
将被设置,但它们是相同的。
现在,如果 i=0
或等于 youngestDate
它确实是 latest
并获得 属性
else if equals oldestDate
它确实是最旧的。
因此我们成功地将两个 GpsDto
对象设置为 latest
,因为它永远不会 运行 else if
语句。
#2 没有数据?
我们做了一些空检查,如果没有数据,我们不会设置特殊属性。
#3 List
?
中只有一个 GpsDto
对象
我们不需要在这里设置任何特殊属性,我的定义是"stateless"我们不知道它是第一个还是最后一个。 (偷懒我)
如果我没有完全错的话我在 O(n)
This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.
Collections.sort(gpsDtoList, new Comparator<T>() {
public int compare(T o1, T o2) {
return -o1.getEreigniszeit().compareTo(o2.getEreigniszeit());
}
});
知道这个事实,我怎么能用符号表示这些项目确实相等,即使列表中有一个 "higher"(隐含的意思是更年轻 timestamp
)
测试数据
假设o2.Ereigniszeit = 0000
和o2.Ereigniszeit = 0000
(这只是一个非常简单和抽象的例子)
症结所在
我稍后会处理这些数据并使用此逻辑在 Leaflet 地图上突出显示最新的 (green)
和最旧的 (red)
对象
if (i == 0) {
properties.put("markerStyle", LATEST);
} else if (i == gpsDtoList.size() - 1) {
properties.put("markerStyle", OLDEST);
}
然而字面意思是equal
,我该如何正确处理呢?
(我正在处理很多 gps 位置,所以任何 O(N^2)
都是不可接受的。)
返回对象为GpsDTO
public class GpsDTO implements Serializable {
....
public Date getEreigniszeit() {
return ereigniszeit;
}
public void setEreigniszeit(Date ereigniszeit) {
this.ereigniszeit = ereigniszeit;
}
我建议你使用NavigableMap
;这些按键排序。
// entries will be sorted by your comparator
NavigableMap<Date, List<GpsDTO>> map = new TreeMap<yourComparator>();
// if there is a list already, it will be used; otherwise, a new one will be created
gpsDtoList.forEach(dto ->
map.computeIfAbsent(dto.getEreigniszeit(), new ArrayList<>())
.add(dto));
// iterate the relevant lists to set the respective markers
map.firstEntry().forEach(dto -> dto.setOldest());
if (map.size() > 1) {
map.lastEntry().forEach(dto -> dto.setNeweset());
}
这里没有 lambda 表达式:
NavigableMap<Date, List<GpsDTO>> map = new TreeMap<yourComparator>();
for (GpsDTO dto : gpsDtoList) {
List<GpsDTO> list = map.computeIfAbsent(dto.getEreigniszeit());
list.add(dto);
}
for (GpsDTO firstDto : map.firstEntry()) {
setOldestProperty(firstDto);
}
if (map.size() > 1) {
for (GpsDTO lastDto : map.lastEntry()) {
setNewestProperty(lastDto);
}
}
解决方案
首先我确定最新和最旧的日期。
Date youngestDate = null;
Date oldestDate = null;
Collections.sort(gpsDtoList, new Comparator<T>() {
public int compare(T o1, T o2) {
return -o1.getEreigniszeit().compareTo(o2.getEreigniszeit());
}
});
if (gpsDtoList != null && gpsDtoList.size() > 1) {
youngestDate = gpsDtoList.get(0).getEreigniszeit();
oldestDate = gpsDtoList.get(gpsDtoList.size() - 1).getEreigniszeit();
}
和实际设置逻辑
if (youngestDate != null && oldestDate != null) {
if (i == 0 || youngestDate.equals(gpsDtoList.get(i).getEreigniszeit())) {
properties.put("markerStyle", LATEST);
} else if (oldestDate.equals(gpsDtoList.get(i).getEreigniszeit())) {
properties.put("markerStyle", OLDEST);
}
}
测试用例/解释
#1 o1,o2
等于?
youngestDate
和 oldestDate
将被设置,但它们是相同的。
现在,如果 i=0
或等于 youngestDate
它确实是 latest
并获得 属性
else if equals oldestDate
它确实是最旧的。
因此我们成功地将两个 GpsDto
对象设置为 latest
,因为它永远不会 运行 else if
语句。
#2 没有数据?
我们做了一些空检查,如果没有数据,我们不会设置特殊属性。
#3 List
?
中只有一个 GpsDto
对象
我们不需要在这里设置任何特殊属性,我的定义是"stateless"我们不知道它是第一个还是最后一个。 (偷懒我)
如果我没有完全错的话我在 O(n)