【问题标题】:How to find duplicates in a list of list of objects in java如何在java中的对象列表中查找重复项
【发布时间】:2022-01-07 12:05:42
【问题描述】:

假设我在对象数组列表中有一个数据compositeKeyValues = [["READ", "3GPP_ACCESS"], ["CREATE", "NON_3GPP"], ["READ", "3GPP_ACCESS"], ["MODIFY", "NON_3GPP"]]

List<Object> compositeKeyValues = new ArrayList<>();

我想识别该外部列表中的重复列表,该列表包含相同的值,例如在索引 0 和 2 处,列表是相同的。我怎样才能在列表中识别出类似的东西?

【问题讨论】:

    标签: java list object arraylist duplicates


    【解决方案1】:

    其实你有:

    List<List<String>> compositeKeyValues;
    

    如果列表具有相同顺序的相同元素,则列表是相等的 - 就像您的示例一样。

    查找重复的内部列表与查找其他更简单类型的重复项没有什么不同。

    这是一种方法:

    List<List<String>> duplicates = compositeKeyValues.stream()
        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
        .entrySet().stream()
        .filter(e -> e.getValue().intValue() > 1)
        .map(Map.Entry::getKey)
        .collect(Collectors.toList());
    

    即使您将列表的类型保留为List&lt;Object&gt;,此代码也将起作用,但结果也将具有类型List&lt;Object&gt;。但是,建议使用更具体的类型List&lt;List&lt;String&gt;&gt;,并且更有用

    【讨论】:

    • 虽然不推荐使用List&lt;Object&gt;List&lt;List&lt;String&gt;&gt; 是要走的路。
    • 再来一个查询,这里使用 grouping by 、identity() 和counting() 方法的确切导入语句是什么?
    • @misbhaafreen 我已将类名添加到代码中以使其更清晰。使用import java.util.function.Function; import java.util.stream.Collectors;。您可以使用x -&gt; x 代替Function.identity()
    【解决方案2】:

    我会首先不列出通用的Object 实例,因为这会使它更难完成。将对象列表改为特定类。然后,您的自定义类必须覆盖 Object 的 equal()hashCode() 方法。

    现在的问题是,实现实际删除重复项的最简单方法是什么。简单的答案是将您的List 转换为Set。我认为这样的事情应该可行。

    Set<SomeType> mySet = myList.findByType(type)
            .stream()
            .map(ClassName::getValue)
            .collect(Collectors.toSet());
    

    请记住,我提到的方法仍然需要被覆盖。大多数(如果不是全部)现代 IDE 都有方便的方法来覆盖 equals() 和 hashCode()` 方法。

    【讨论】:

    • 我确实尝试过比较列表和集合的大小,但集合并没有消除这些,而且这里的东西是动态的,所以我认为我不能从中做出任何特定的类。
    • @misbhaafreen 您是否从Object 类中覆盖了equalshashCode?我猜你没有。如果您不覆盖这些方法,将无法确定两个不同对象的内部值是否相同。因此,它们不会被发现并随后被删除。
    【解决方案3】:

    即使最初的问题是关于列表的,我也想贡献一个基于数组的解决方案。

    import java.util.Arrays;
    
    public class Main {
    
        public static void main(String[] args) {
    
            String[][] data = { { "READ", "3GPP_ACCESS" }, { "CREATE", "NON_3GPP" }, { "READ", "3GPP_ACCESS" },
                    { "MODIFY", "NON_3GPP" } };
    
            for (int i = 0; i < data.length; i++)
                for (int j = i + 1; j < data.length; j++) {// should not compare with itself and anything previously else
                                                            // there will be double findings like 0,2 and 2,0
    
                    if (Arrays.equals(data[i], data[j])) // check for equality
    
                        System.out.println("Match found at " + i + " " + Arrays.toString(data[i]) + " and " + j + " "
                                + Arrays.toString(data[j]));
    
                }
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      试试这个:

      java.util.List<String> list = Arrays.asList("READ", "3GPP_ACCESS","CREATE", "NON_3GPP","READ", "3GPP_ACCESS","MODIFY", "NON_3GPP");
              for (int i = 0; i < list.size(); i++) {
                  for (int j = i+1; j <list.size() ; j++) {
                      if(list.get(i).equals(list.get(j))){
                          System.out.println(list.get(i));
                      }
                  }
              }
      

      【讨论】: