java - 使用 Lambda API 比较 ArrayList 的多个字段并收集对象
问题描述
我在我的项目中面临类似于下面描述的情况,其中我无法实现代码。
我有一个 POJO 类
public class TranObject {
public String loadId;
public String vDate;
public String dDate;
public String pDate;
public TranObject(String loadId, String vDate, String dDate, String pDate) {
super();
this.loadId = loadId;
this.vDate = vDate;
this.dDate = dDate;
this.pDate = pDate;
}
//Getter and Setters
//toString()
}
现在我有另一个处理器类,我想在我通过数据服务调用接收的 tranload 对象之间实现一些比较,并将它们收集到另一个集合中。 实现逻辑在下面的评论中给出。请阅读以下评论
import java.util.Arrays;
import java.util.List;
public class DemoClass {
public static void main(String[] args) {
List<TranObject> listObj = Arrays.asList(
new TranObject("LOAD1", "20180102", "20180202", null),
new TranObject("LOAD2", "20180402", "20180403", null),
new TranObject("LOAD3", "20180102", "20180202", "20190302"),
new TranObject("LOAD4", "20180402", "20180403", null),
new TranObject("LOAD5", "20200202", "20200203", null)
);
/*
IF (obj1, obj3 vdate and dDate are equal)
IF(pDate == null for obj1 or obj3)
THEN obj1 and obj3 are equal/duplicates, and we collect them.
ELSE IF(pDate != null for obj1 and obj3)
IF(pDate is same for obj1 and obj3)
THEN obj1 and obj3 are duplicates, and we collect them.
ELSE
THEN obj1 and obj3 are unique.
*/
}
}
我的最终结果应该是一个像 List 这样的集合,其中包含重复的 Tran 对象以供进一步更新。
我搜索了互联网以了解如何使用 Lambda API 解决它。-> 尝试先使用 groupingBy 和 vDate,然后使用 dDate,但后来我无法比较它们的 pDate 是否相等。
谁能帮我解决这个问题。一点帮助对我很有帮助。我被困在这里
更新: 经过一番阅读,我试图通过覆盖 POJO 类中的 equals 方法来实现相同的功能,如下所示:
@Override
public boolean equals(Object obj) {
boolean isEqual=false;
if(obj!=null) {
TranObject tran = (TranObject) obj;
isEqual=(this.vDate.equals(tran.getvDate()) && this.dDate.equals(tran.getdDate()));
if(isEqual && this.pDate != null && tran.getpDate()!= null) {
isEqual = (this.pDate.equals(tran.getpDate()));
}
}
return isEqual;
}
仍然没有按预期工作......有人可以帮我解释为什么吗?
解决方案
最接近您的要求将以嵌套方式分组,然后过滤内部以适应Map
各种条件,同时最终只对值感兴趣。
Stream<Map<String, List<TranObject>>> groupedNestedStream = listObj.stream()
.collect(Collectors.groupingBy(a -> Arrays.asList(a.vDate, a.dDate)
, Collectors.groupingBy(t -> t.pDate == null ? "default" : t.pDate)))
.values().stream();
从这些分组中,值(来自地图)符合条件的条件是
- 在这种情况下,它们都相同
pDate
,innerMap 将只有一个带有 commonpDate
(m.size() == 1
)的条目 - 分组后的值之一恰好
pDate
为null
(含义m.containsKey("default") && m.get("default").size() == 1
)
List<TranObject> tranObjects = groupedNestedStream
.filter(m -> m.size() == 1 || (m.containsKey("default") && m.get("default").size() == 1))
.flatMap(m -> m.values().stream().flatMap(List::stream))
.collect(Collectors.toList());
请注意,使用"default"
字符串常量来避免在收集Map
带有null
键或值的 a 时失败(或不良做法)。
推荐阅读
- python - Python:如何在打印函数中添加带有变量的新行
- c# - TripleDES Decryptor 在第一次调用 TransformBlock 时什么也不做
- python-3.x - 类变量会在python中自行重置为初始值吗?
- mysql - 基于其他选择的mysql选择
- java - 组件未出现在 ContentPane 中
- c++ - 如果用户输入“q”,程序退出
- react-native - Expo + React Native 版本不匹配错误(JavaScript 版本:0.55.4,Native 版本:0.57.1)
- html - 字段在 iOS 浏览器上未正确显示
- xamarin - Xamarin 表单上的自定义地图图钉
- javascript - 如何将大整数拆分为 8 位整数数组