检查多个对象是否具有 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;
   }
)