根据条件比较数组列表中的对象字段值,如果条件为真则移除
Compare object field values in array list based on conditions and remove if condition is true
假设这些是 java bean 类-
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。
例如。如果我有 2 条记录具有相同的 Camp.getUser().getId()
但 record 1
的 CreateDt
大于 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());
}
解释 : 你的 Comparator
目前没有 return 两个日期可能是 equal
的情况下的任何值,你应该只依赖 Date
class 的 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 如何工作的解释
假设这些是 java bean 类-
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。
例如。如果我有 2 条记录具有相同的 Camp.getUser().getId()
但 record 1
的 CreateDt
大于 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());
}
解释 : 你的 Comparator
目前没有 return 两个日期可能是 equal
的情况下的任何值,你应该只依赖 Date
class 的 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();