根据条件比较数组列表中的对象字段值,如果条件为true则删除



假设这些是javabean类-

class Camp {
int number;
User userId;
Date createDt;
}
class User {
private String id;
private String name;
}

我想从类型为Camp的arrayList中删除那些具有相同userId但createDt较小的记录。

假设这是列表-

// ... the list is already populated
List<Camp> usersList = populatedListOfUser();

这就是方法

private List<Camp> skipByComparison(List<Camp> usersList){
List<Camp> mainList = new ArrayList<Camp>();
Set<Camp> s = new TreeSet<Camp>(new Comparator<Camp>() {
@Override
public int compare(Camp o1, Camp o2) {
if(o1.getUserId().getId().equals(o2.getUserId().getId())) {
if(o1.getCreatedTs().compareTo(o2.getCreatedTs()) < 0) {
usersList.remove(o1);
return -1;
} else {
return 1;
}
} else {
return 0;
}
}
});
s.addAll(usersList);
mainList.addAll(s);
}

所以当我打电话给

usersList = skipByComparison(usersList);

我没有从类型为Camp的arrayList中获得具有相同userId但较少createDt的记录。

例如,如果我有两个具有相同Camp.getUser().getId()的记录,但record 1CreateDt大于record 2,那么我想删除record 2

您可以将代码更新为:

private List<Camp> skipByComparison(List<Camp> usersList){
Set<Camp> s = new TreeSet<>((o1, o2) -> o1.getUserId().getId().equals(o2.getUserId().getId()) ? 
o1.getCreateDt().compareTo(o2.getCreateDt()) : 0);
s.addAll(usersList);
return new ArrayList<>(s);
}

或者更好的是,你可以使用Collectors和流来解决它:

private List<Camp> skipByComparisonStream(List<Camp> usersList) {
return new ArrayList<>(usersList.stream()
.collect(Collectors.toMap(c -> c.getUserId().getId(),
Function.identity(),
(a, b) -> a.getCreateDt().after(b.getCreateDt()) ? a : b))
.values());
}

解释:当两个日期可能是equal时,您的Comparator当前没有返回任何值,您可能只需要依靠Date类的compareTo实现:

Set<Camp> s = new TreeSet<>(new Comparator<Camp>() {
@Override
public int compare(Camp o1, Camp o2) {
return o1.getUserId().getId().equals(o2.getUserId().getId()) 
? o1.getCreateDt().compareTo(o2.getCreateDt()) : 0;
}
});

完成此操作后,可以使用lambda表达式将其简化为:

Set<Camp> s = new TreeSet<>((o1, o2) -> o1.getUserId().getId().equals(o2.getUserId().getId())
? o1.getCreateDt().compareTo(o2.getCreateDt()) : 0);

我所做的其余修改是简化执行顺序并清除多余的初始化。

旁白:我刚刚在另一个问题中得到更正,建议您也使用java.time.LocalDate作为createDt属性。

您可以使用toMap收集器:

Collection<Camp> values = usersList.stream()
.collect(toMap(c -> c.getUser().getId(),
Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Camp::getCreateDt))))
.values();

有关toMap如何在中工作的解释,请参阅此答案

相关内容

最新更新