java - 如何根据字符串的组合删除重复项?
问题描述
我想比较getA
(例如:123)和getB
(例如:456)并找到重复的记录。
P1 getA getB
1 000123000 456
P2 getA getB
2 000123001 456
我在下面尝试过,但它会根据getA
&getB
组合找到重复项:
Map<Object, Boolean> findDuplicates = productsList.stream().collect(Collectors.toMap(cm -> Arrays.asList(cm.getB(),cm.getA().substring(3, cm.getCode().length() - 3)), cm -> false, (a, b) -> true));
现在我正在尝试删除cm.getA
价值最低但无法在此处使用 comapartor 的记录:
productsList.removeIf(cm -> cm.getA() && findDuplicates .get(Arrays.asList(cm.getB(),cm.getA().substring(3, cm.getA().length() - 3))));
任何帮助,将不胜感激?
解决方案
您可以通过两个步骤来完成
Function<Product,Object> dupKey = cm ->
Arrays.asList(cm.getB(), cm.getA().substring(3, cm.getA().length() - 3));
Map<Object, Boolean> duplicates = productsList.stream()
.collect(Collectors.toMap(dupKey, cm -> false, (a, b) -> true));
Map<Object,Product> minDuplicates = productsList.stream()
.filter(cm -> duplicates.get(dupKey.apply(cm)))
.collect(Collectors.toMap(dupKey, Function.identity(),
BinaryOperator.minBy(Comparator.comparing(Product::getA))));
productsList.removeAll(minDuplicates.values());
首先,它识别有重复的键,然后,它收集每个键的最小值,跳过没有重复的元素。最后,删除选定的值。
原则上,这可以一步完成,但是,它需要一个对象保存这两个信息,是否有特定键的重复项以及它们的最小值:
BinaryOperator<Product> min = BinaryOperator.minBy(Comparator.comparing(Product::getA));
Set<Product> minDuplicates = productsList.stream()
.collect(Collectors.collectingAndThen(
Collectors.toMap(dupKey, cm -> Map.entry(false,cm),
(a, b) -> Map.entry(true, min.apply(a.getValue(), b.getValue()))),
m -> m.values().stream().filter(Map.Entry::getKey)
.map(Map.Entry::getValue).collect(Collectors.toSet())));
productsList.removeAll(minDuplicates);
这使用Map.Entry
实例来保存两个不同类型的值。为了保持代码的可读性,它使用 Java 9 的Map.entry(K,V)
工厂方法。当需要支持 Java 8 时,建议创建自己的工厂方法以保持代码简单:
static <K, V> Map.Entry<K, V> entry(K k, V v) {
return new AbstractMap.SimpleImmutableEntry<>(k, v);
}
然后使用该方法而不是Map.entry
.
逻辑与第一个变体中的逻辑相同,它将值映射到false
元素本身并将它们合并到true
最小元素,但现在一次完成。过滤必须在之后进行,以跳过false
元素,然后映射到最小元素并将它们收集到一个Set
.
然后,使用removeAll
是一样的。
推荐阅读
- python-3.x - po2html 缺少 html 模板
- python - Python:获取子列表中的每个第一个、第二个、第三个元素
- java - Java 代码如何在 Jenkins 构建期间读取 Jenkins Global 凭据?
- sql - 不使用 EXISTS 引入子查询时,选择列表中只能指定一个表达式。(子查询)重复
- python - 在python(jupyter)中复制一个变量/使用具有相同变量的不同函数
- excel - 单击单元格,通过链接图片显示数据范围
- gcc - 将 gcc-8.2.0 与 musl 静态链接的补丁
- kdb - (q/kdb+) 使用前一行的结果更新行
- php - Laravel - 如果查询为空,则返回不同的查询
- vb.net - 如何将 Linq 结果转换为数据表(使用数据表而不是上下文)