【问题标题】:Find duplicate fields in a list of list of objects在对象列表中查找重复字段
【发布时间】:2021-08-26 08:37:41
【问题描述】:

我有一个这样的对象列表:

[{
     supplier: ""
     rating: [{
        sid: "1"
    },
    {
       sid:"1"
    }]
   }]

我想检查每个评分的 sid 在 Java 中是否没有重复项 该类看起来像:

class Entity {
  private String supplier;
  private List<Rating> ratings;
}



class Rating {
    String sid;
    String bar;
}

在每个ratings 内,不会有重复的sid

这是通过 PUT 调用保存到 mongo 的,所以我不确定通过添加索引在 Mongo 中做类似的事情是否合理。

编辑:结构是这样的

List<List<Rating>> dupCheck = ratings.stream().map(p -> p.getRating()).collect(Collectors.toList());

List<Entity>

所以当我调用它时,它会询问我试图通过 IntStream 解决但无法解决的索引。

更新:对不起,我不清楚。我想检测一个实体中的重复项(在 sid 字段上)。

new Entity("A",
                Arrays.asList(
                        new Rating("1", "a"),
                        new Rating("2", "b"),
                        new Rating("3", "c"),
                        new Rating("1", "d")
                )),

所以在上面我想检测是否有重复的sids

【问题讨论】:

    标签: java java-8 duplicates java-stream


    【解决方案1】:

    要检查您是否重复了sids,您可以这样做:

    List<Entity> entities = Arrays.asList(
            new Entity("A",
                    Arrays.asList(
                            new Rating("1", "a"),
                            new Rating("2", "b"),
                            new Rating("3", "c"),
                            new Rating("4", "d")
                    )),
            new Entity("B",
                    Arrays.asList(
                            new Rating("1", "a"),
                            new Rating("5", "e")
                    ))
    );
    
    
    Map<String, Long> sidToCount = entities.stream()
            .map(Entity::getRatings)
            .flatMap(ratings -> ratings.stream().map(Rating::getSid)) // stream of sids
            .collect(Collectors.groupingBy(s -> s, Collectors.counting()));
    
    boolean hasDuplicates = sidToCount.values()
            .stream()
            .anyMatch(count -> count > 1);
    
    System.out.println(hasDuplicates); // true
    

    编辑:

    要查找实体是否有重复的评级,您可以:

    boolean hasEntityWithDuplicates = entities.stream()
            .map(Entity::getRatings)
            .anyMatch(ratings -> ratings.size() > new HashSet<>(ratings).size());
    

    通过创建Set,我们可以计算唯一元素的数量。如果集合的大小小于列表的大小,则表示列表包含重复项。

    【讨论】:

    • 感谢您的回答。这将考虑所有展平值中的 sid。是否可以对其进行调整以在一个实体中查找重复项?
    • 查找一个实体中是否存在重复项或返回一个实体中的重复项?
    • 检测没问题,我想一检测到重复就抛出异常
    【解决方案2】:

    您可以使用哈希集来确定您的列表是否有重复项:

    Set<String> sids = new HashSet<>();
    
    // `numDuplicates` returns the number of duplicate ratings
    long numDuplicates = ratings.stream()
        .map(r -> r.sid)
        // HashSet#add returns `true` if the element was not yet in the HashSet, and `false` if the HashSet already contained the element.
        .filter(s -> !sids.add(s))
        // Count the number of elements already contained.
        // here you could also use `collect` if you want to find out which ratings are duplicated.
        .count();
    
    if (numDuplicates > 0) {
        // there are duplicates
    }
    

    【讨论】:

    • 更新帖子,对象列表在主列表中