在ArrayList中创建重复项的列表

时间:2018-05-17 11:48:33

标签: java arraylist collections

我正在使用一个集合从ArrayList(从数据库填充)中获取重复项的列表

void getDuplicateHashTest() {
        List<BroadcastItem> allDataStoreItems  = itemsDAO.getAllItems();
        Set<BroadcastItem> setOfAllData = new HashSet<>(allDataStoreItems);
        List<BroadcastItem> diff = new ArrayList<>(setOfAllData);
        allDataStoreItems.removeAll(diff);
}

所以在最后一行,所有不重复的项目都应该从所有项目的列表中删除。

问题是当我打印allDataStoreItems.size()时我得到0

设置和子列表打印正确的项目数。

我做错了什么?

3 个答案:

答案 0 :(得分:2)

List#removeAll删除所有出现的给定元素,而不仅仅是其中一个(与List#remove相反,后者仅删除第一次出现)。因此setOfAllData包含列表中每个元素的一个副本,然后删除每个元素的所有匹配项,这意味着您总是会以空列表结束。

要知道如何解决这个问题,我需要了解更多关于你想要的结果。你想要删除每个元素的一个副本吗?如果是这样,你可以用:

List<BroadcastItem> allDataStoreItems  = itemsDAO.getAllItems();
Set<BroadcastItem> setOfAllData = new HashSet<>(allDataStoreItems);
setOfAllData.forEach(allDataStoreItems::remove);

答案 1 :(得分:2)

如果你只想存储重复项就很简单,找到下面的代码。

Set<BroadcastItem> duplicates = new HashSet<>;
Set<BroadcastItem> allItems=new HashSet<> 
for(BroadcastItem b:allDataStoreItems){
      boolean x=allItems.add(b);
      if(x==false){
             duplicates.add(b); 
       }

}

答案 2 :(得分:1)

正如answer by jacobm中已经指出的那样:Collection#removeAll方法将删除所有特定元素的出现。但是,创建列表并重复调用remove的替代方案并不是一个很好的解决方案:在List上,remove调用通常会有O(n)复杂度,因此找出像这样的重复将具有二次复杂性。

更好的解决方案是shamsher Khan in his answer (+1!)已经提到的解决方案:您可以使用Set遍历列表,并跟踪已经看到的元素。

该解决方案具有O(n)的复杂性。

目前尚不清楚是否需要所有重复项的列表。例如,当输入为[1, 2,2,2, 3]时,结果应为[2,2]还是[2]?但是,您可以简单地计算重复项的列表,并在必要时在第二步中使其元素唯一。

以下是一个例子:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class FindDuplicatesInList
{
    public static void main(String[] args)
    {
        List<Integer> list = Arrays.asList(0,1,1,1,2,3,3,4,5,6,7,7,7,8);

        List<Integer> duplicates = computeDuplicates(list);

        // Prints [1, 1, 3, 7, 7]
        System.out.println(duplicates);

        // Prints [1, 3, 7]
        System.out.println(makeUnique(duplicates));
    }

    private static <T> List<T> makeUnique(List<? extends T> list)
    {
        return new ArrayList<T>(new LinkedHashSet<T>(list));
    }

    private static <T> List<T> computeDuplicates(List<? extends T> list)
    {
        Set<T> set = new HashSet<T>();
        List<T> duplicates = new ArrayList<T>();
        for (T element : list)
        {
            boolean wasNew = set.add(element);
            if (!wasNew)
            {
                duplicates.add(element);
            }
        }
        return duplicates;
    }
}