java - 比较来自 findAll() 的 java 元素

标签 java spring list repository crud

我必须从从 CrudRepository 检索到的对象列表中删除重复项。

我做到了:

if (!prospectionRepository.findAll().isEmpty()) {
    List<Prospection> all = prospectionRepository.findAll();
    for (int i = 0; i < all.size()-1; i++) {
        for (int k = i+1;k < all.size(); k++) {
            if (all.get(i).getProspectNumber() == all.get(k).getProspectNumber()) {
                all.remove(all.get(i));
            }
        }
    }
    prospectionRepository.save(all);
}

但是,不会从列表中删除重复项,然后在我不想的时候保留它们。

最佳答案

问题编辑

在聊天对话之后,必须考虑额外的参数:

  1. multiples Prospect may have the same prospect number but they do have an unique primary key in the database. Consequently, the duplicate filter cannot rely on the Prospect equality
  2. a Prospect has a visited status which defined whether the Prospect has been contacted by the company or not. The two main status are NEW and MET. Only one Prospect can be MET. Other duplicates (with the same prospect number) can only be NEW

算法

问题需要额外的步骤才能解决:

  1. 潜在客户需要按 prospect number 分组.在这个阶段,我们将 <ProspectNumber, List<Prospect>>映射。然而,List<Prospect>必须根据前面定义的规则以单个元素结束
  2. 在列表中,如果未满足潜在客户并且发现另一个具有满足状态的潜在客户,则第一个潜在客户将被丢弃

因此,列表将按照以下规则生成:

  • 如果潜在客户在潜在客户编号方面没有重复项,则无论其状态如何都将保留
  • 如果潜在客户在潜在客户编号方面有重复,则只有 met一个被保留
  • 如果多个潜在客户具有相同的潜在客户编号但没有一个是 met ,然后满足任意一个:Stream不保证按列表顺序循环。

代码

诀窍是通过 Map因为 key 将保持唯一性。如果您的预期号码是特定类型,这将假定 equals()hashCode()被正确定义。

免责声明:代码未经测试

List<Prospection> all = prospectionRepository.findAll().stream()
        // we instantiate here a Map<ProspectNumber, Prospect>
        // There is no need to have a Map<ProspectNumber, List<Propect>> 
        // as the merge function will do the sorting for us
        .collect(Collectors.toMap(
                // Key: use the prospect number
                prospect -> prospect.getProspectNumber(),
                // Value: use the propect object itself
                prospect -> prospect,
                // Merge function: two prospects with the same prospect number
                // are found: keep the one with the MET status or the first one
                (oldProspect, newProspect) -> {
                    if(oldProspect.getStatus() == MET){
                        return oldProspect;
                    } else if (newProspect.getStatus() == MET){
                        return newProspect;
                    } else{
                        // return the first one, arbitrary decision
                        return oldProspect;
                    }
                }
        ))
        // get map values only
        .values()
        // stream it in order to collect its as a List
        .stream()
        .collect(Collectors.toList());
prospectionRepository.save(all);

Map.values()实际上返回一个 Collection .所以如果你的 prospectionRepository.save(...)可以接受 Collection (不仅是 List ),你可以走得更快。我还使用以下同义词:

  • static method reference : Prospect::getProspectNumberFunction相当于prospect -> prospect.getProspectNumber()
  • Function.identity() :相当于prospect -> prospect
  • 三元运算符:它返回相同的东西但写法不同
Collection<Prospection> all = prospectionRepository.findAll().stream()
        .collect(Collectors.toMap(
                Prospect::getProspectNumber,
                Function.identity(),
                (oldProspect, newProspect) -> newProspect.getStatus() == MET ? newProspect : oldProspect
        )).values();
prospectionRepository.save(all);

<子> 供您引用,如果两个 Prospection具有相同的ProspectNumber是相等的,那么一个简单的 distinct() 就足够了:

List<Prospection> all = prospectionRepository.findAll()
        .stream()
        .distinct()
        .collect(Collectors.toList());
prospectionRepository.save(all);

关于java - 比较来自 findAll() 的 java 元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46715510/

相关文章:

r - 使用 lapply 处理列表内容

java - 控制台输出中的 IntelliJ IDEA 编码不正确

spring - 发出 POST 请求时如何不转义 Spring RestTemplate 中的表单正文字符?

java - Spring Boot 应用程序通过 HTTPS 调用另一个 Spring Boot 应用程序并获取 SSL 证书验证错误 : "signature check failed"

java - 为 spring ConfigurationProperties 子类使用构造函数注入(inject)

python - 通过重复应用函数创建列表

list - 分割 Haskell 列表

java - 抽象类和接口(interface)在 JVM 中的存储方面有什么区别

java - 对于安全随机类型,方法 nextInt 未定义

java - Quartz 运行一次作业