我想比较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))));
有什么帮助吗?
答案 0 :(得分:0)
您可以将字符串设为数组列表,然后遍历数组列表,然后将其与其他数组列表进行比较。
答案 1 :(得分:0)
您可以通过两个步骤完成
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
是相同的。
答案 2 :(得分:0)
您可以使用重复键和TreeSet的映射,而不是将重复键映射为boolean。这将使其一步之遥。就像在TreeSet中一样,元素始终保持排序状态,您无需在下一步中对其进行排序即可找到最小值。
public class ProductDups {
public static void main(String[] args) {
List<Product> productsList = new ArrayList<>();
productsList.add(new Product("000123000", "456"));
productsList.add(new Product("000123001", "456"));
productsList.add(new Product("000124003", "567"));
productsList.add(new Product("000124002", "567"));
List<Product> minDuplicates = productsList.stream()
.collect(
Collectors.toMap(
p -> Arrays.asList(p.getB(),
p.getA().substring(3, p.getA().length() - 3)),
p -> {
TreeSet<Product> ts = new TreeSet<>(Comparator.comparing(Product::getA));
ts.addAll(Arrays.asList(p));
return ts;
},
(a, b) -> {
a.addAll(b);
return a;
}
)
)
.entrySet()
.stream()
.filter(e -> e.getValue().size() > 1)
.map(e -> e.getValue().first())
.collect(Collectors.toList());
System.out.println(minDuplicates);
}
}
class Product {
String a;
String b;
public Product(String a, String b) {
this.a = a;
this.b = b;
}
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
@Override
public String toString() {
return "Product{" +
"a='" + a + '\'' +
", b='" + b + '\'' +
'}';
}
}