如何在java中的对象列表中查找重复项

Posted

技术标签:

【中文标题】如何在java中的对象列表中查找重复项【英文标题】:How to find duplicates in a list of list of objects in 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 处,列表是相同的。我怎样才能在列表中识别出类似的东西?

【问题讨论】:

【参考方案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));
                
            
        

【讨论】:

以上是关于如何在java中的对象列表中查找重复项的主要内容,如果未能解决你的问题,请参考以下文章

如何查找重复项并保留以后的条目

csharp 如何在SelectListItem对象列表中返回重复项

C# LINQ 在列表中查找重复项

如何删除已经在list中的重复项

在 Python 元组列表中查找重复项

删除列表中的重复对象 (C#)