首页 > 解决方案 > 如何识别列表中的重复记录?

问题描述

我有以下问题:

我想从 Vo 列表中删除重复数据,具体取决于注册字段是否相同,我向您展示了我正在尝试的解决方案。然后这是我正在制作的列表中的数据

List<MyVo> dataList = new ArrayList<MyVo>();

MyVo  data1 = new MyVo();
data1.setValidated(1);
data1.setName("Fernando");
data1.setRegistered("008982");

MyVo data2 = new MyVo();
data2.setValidated(0);
data2.setName("Orlando");
data2.setRegistered("008986");

MyVo data3 = new MyVo();
data3.setValidated(1);
data3.setName("Magda");
data3.setRegistered("008982");


MyVo data4 = new MyVo();
data4.setValidated(1);
data4.setName("Jess");
data4.setRegistered("006782");

dataList.add(data1);
dataList.add(data2);
dataList.add(data3);
dataList.add(data4);

我必须做的第一件事是将它分成两个不同的列表,具体取决于数据是否经过验证,因为注册的值是经过验证的。

List<MyVo> registeredBusinesses = new ArrayList<MyVo>();
List<MyVo> unregisteredBusinesses = new ArrayList<MyVo>();

for (MyVo map : dataList) {
    if (map.getValidated == 0) {
        unregisteredBusinesses.add(map);
    }else {
        registeredBusinesses.add(map);
    }
}

现在注册企业列表我想从其注册字段中删除以相同值重复的数据并创建一个新列表。这就是它所需要的,但它不能正常工作

List<MyVo> duplicateList = registeredBusinesses.stream().filter(distictByRegistered(MyVo::getRegistered)).collect(Collectors.toList());


public static <T> Predicate<T> distictByRegistered(Function<?      super T, ?> keyExtractor) {
    Set<Object> seen = ConcurrentHashMap.newKeySet();
    return t -> seen.add(keyExtractor.apply(t));
}

但是使用这种方法我得到以下输出:

{[“已验证”:1,“名称”:“费尔南多”,“注册”:“008982”],[“已验证”:1,“名称”:“杰西”,“注册”:“006782”]}

我想获得的输出如下:

未注册企业名单:

{["validated":0,"name":"Orlando","registered":"008986"]}

注册企业名单:

{["validated":1,"name":"Jess","registered":"006782"]}

注册的DuplicateBusinesses 列表:

{["validated":1,"name":"Fernando","registered":"008982"], 
["validated":1,"name":"Magda","registered":"008982"]}

我不知道该怎么做,你能帮帮我吗?我想使用 lambdas 来减少代码,例如当我分成两个列表时的第一个

标签: javalambdapartitioning

解决方案


您的方法看起来几乎是正确的,分组依据Function.identity()将正确标记重复项(基于 equals() 实现!),如果您有一个对象中的唯一属性/ID,您也可以分组,您缺少的是操纵结果映射以获取包含所有重复项的列表。我添加了描述这里发生的事情的评论。

List<MyVo> duplicateList = registeredBusinesses.stream()
    .collect(Collectors.groupingBy(Function.identity()))
    .entrySet()
    .stream()
    .filter(e -> e.getValue().size() > 1) //this is a stream of Map.Entry<MyVo, List<MyVo>>, then we want to check value.size() > 1
    .map(Map.Entry::getValue) //We convert this into a Stream<List<MyVo>>
    .flatMap(Collection::stream) //Now we want to have all duplicates in the same stream, so we flatMap it using Collections::stream
    .collect(Collectors.toList()); //On this stage we have a Stream<MyVo> with all duplicates, so we can collect it to a list.

此外,您还可以使用流 API 拆分dataList为已注册和未注册。

首先我们isUnregistered在 MyVo 中创建一个方法

public boolean isUnregistered() {
  return getrRegistered() == 0;
}

然后

Map<Boolean, List<MyVo>> registeredMap = dataList.stream().collect(Collectors.groupingBy(MyVo::isUnregistered));

map.get(true)将在哪里unregisteredBusinessesmap.get(false) registeredBusinesses


推荐阅读