检查多个对象是否具有 java 中字段的相同值,并根据其他字段删除重复项
Check if multiple objects have same value of a field in java and remove duplicates based on other fields
所以我有一个对象列表。假设他们有 2 个字段 startDate,endDate(数据类型是时间戳)。因此,如果 startDate 等于另一个对象的 startDate,那么我必须选择具有更高 endDate 的对象。我怎样才能有效地实现这一目标。我可以使用 2 个 for 循环,但这会产生很高的时间复杂度。有什么更好的方法吗?谢谢
流式处理您的列表,使用您的对象开始日期作为键来收集映射,如果两个或多个对象具有相同的开始日期,则使用合并函数通过比较结束日期来决定要映射到哪个对象。类似于:
Collection<YourObject> result =
yourList.stream()
.collect(Collectors.toMap(YourObject::getStartDate,
Function.identity(),
(a, b) -> a.getEndDate().after(b.getEndDate()) ? a : b))
.values();
下面是一个使用 Integer
而不是日期的示例,以使其更易于阅读,但原理是相同的。只需更改比较运算符以适应并确保您的日期 class 可用作地图键。
测试class:
class Test {
final Integer start;
final Integer end;
public Test(Integer s, Integer e) {
this.start = s;
this.end = e;
}
@Override
public String toString() {
return start + " " + end;
}
}
使用 Test
class:
的几个实例的代码示例
List<Test> l = Arrays.asList(new Test(1, 2), new Test(3, 4), new Test(1, 3), new Test(1, 1));
Map<Integer, Test> m = l.stream()
.collect(
Collectors.toMap(
o -> o.start,
Function.identity(),
(e, r) -> r.end > e.end ? r : e));
m.values().forEach(System.out::println);
输出:
1 3
3 4
例如,您可以使用 HashMap
并利用 compute
method:
hashMap.compute(newObject.getStartDate(), (key, value) ->
if (value == null) {
newObject;
} else if (value.getEndDate().after(newObject.getEndDate())) {
value;
} else {
newObject;
}
)
所以我有一个对象列表。假设他们有 2 个字段 startDate,endDate(数据类型是时间戳)。因此,如果 startDate 等于另一个对象的 startDate,那么我必须选择具有更高 endDate 的对象。我怎样才能有效地实现这一目标。我可以使用 2 个 for 循环,但这会产生很高的时间复杂度。有什么更好的方法吗?谢谢
流式处理您的列表,使用您的对象开始日期作为键来收集映射,如果两个或多个对象具有相同的开始日期,则使用合并函数通过比较结束日期来决定要映射到哪个对象。类似于:
Collection<YourObject> result =
yourList.stream()
.collect(Collectors.toMap(YourObject::getStartDate,
Function.identity(),
(a, b) -> a.getEndDate().after(b.getEndDate()) ? a : b))
.values();
下面是一个使用 Integer
而不是日期的示例,以使其更易于阅读,但原理是相同的。只需更改比较运算符以适应并确保您的日期 class 可用作地图键。
测试class:
class Test {
final Integer start;
final Integer end;
public Test(Integer s, Integer e) {
this.start = s;
this.end = e;
}
@Override
public String toString() {
return start + " " + end;
}
}
使用 Test
class:
List<Test> l = Arrays.asList(new Test(1, 2), new Test(3, 4), new Test(1, 3), new Test(1, 1));
Map<Integer, Test> m = l.stream()
.collect(
Collectors.toMap(
o -> o.start,
Function.identity(),
(e, r) -> r.end > e.end ? r : e));
m.values().forEach(System.out::println);
输出:
1 3
3 4
例如,您可以使用 HashMap
并利用 compute
method:
hashMap.compute(newObject.getStartDate(), (key, value) ->
if (value == null) {
newObject;
} else if (value.getEndDate().after(newObject.getEndDate())) {
value;
} else {
newObject;
}
)