java - 使用单个匹配字段删除 java 流中的特定重复项
问题描述
给定一个包含以下字段的 java pojo
public class Pojo {
// for brevity I am excluding the property getters / setters etc.
private int V;
private BigDecimal Amount;
private String Operation;
private String Tag;
private String Code;
}
我有一个看起来像这样的 pojos 列表。如果我专门比较标签、数量、版本并忽略代码,我想使用散列/流/任何东西来删除相同标签、数量正好有 1 个“IU”和正好有 1 个“DU”的所有行,和版本。
有没有办法加入或分组流以确保如果对于相同的值恰好有 1 个插入更新“IU”和恰好 1 个删除更新“DU”,那么两者都被删除?
Ver Amount Operation Tag Code
1 1 "IU" 6896450 5500
1 1 "DU" 6898103 5500
2 4 "IU" 6954561 5200
2 4 "DU" 6954561 5500
3 4 "IU" 7057717 5200
3 4 "DU" 7057717 5500
1 8 "IU" 7132952 5200
1 8 "DU" 7132952 5500
解决方案
// import static java.util.stream.Collectors.groupingBy;
List<Pojo> pojos = new ArrayList<>(Arrays.asList(
new Pojo(1, BigDecimal.ONE, "IU", "6896450", "5500"),
// ...,
new Pojo(1, BigDecimal.valueOf(8), "DU", "7132952", "5500")));
// Create a map (`opMapByTag`) by `Tag`,
// within the results/pojos create another map (`pojosByOp`) by `Operation`
Map<String, Map<String, List<Pojo>>> opMapByTag =
pojos.stream().collect(
groupingBy(Pojo::getTag,
groupingBy(Pojo::getOperation)));
Set<Pojo> toBeRemoved = new HashSet<>();
for (Entry<String, Map<String, List<Pojo>>> e : opMapByTag.entrySet())
{
Map<String, List<Pojo>> pojosByOp = e.getValue();
List<Pojo> l1, l2;
if ((pojosByOp.size() == 2) &&
((l1 = pojosByOp.get("IU")).size() == 1) &&
((l2 = pojosByOp.get("DU")).size() == 1))
{
Collections.addAll(toBeRemoved, l1.get(0), l2.get(0));
}
}
pojos.removeIf(toBeRemoved::contains);
pojos.forEach(System.out::println);
推荐阅读
- docker - 是否可以缓存多阶段 docker 构建?
- c++ - 如何反序列化一个数组?
- java - 用forkjoinpool java 8替换线程池
- symfony - 如何在 Symfony 框架中禁用或修复弃用警告?
- python - 如何在python中将特殊格式导入为字典?
- azure-active-directory - 授予服务主体访问其他租户中的应用程序的权限
- python - 将字典存储在文件中并部分加载的最佳方法?
- c - 尝试在 C 中读取 txt 文件时出现分段错误(核心转储)
- xamarin.forms - 带有 XF 的 ReactiveUI:如何为自定义控件创建命令绑定器?
- node.js - NodeJS 真的是单线程还是多线程?