Создайте список дублирующихся элементов в ArrayList - PullRequest
0 голосов
/ 17 мая 2018

Я использую набор для получения списка дублирующихся элементов из 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 голосов
/ 17 мая 2018

Это просто, если вы хотите хранить только дубликаты, найдите следующий код.

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); 
       }

}
0 голосов
/ 17 мая 2018

Как уже указывалось в ответе от jacobm : метод Collection#removeAll удалит все вхождения определенного элемента.Но альтернатива создания списка и повторного вызова remove на самом деле не является хорошим решением: на List вызов remove обычно будет иметь сложность O (n), поэтому вычисление таких дубликатов будет иметь квадратичнуюсложность.

Лучшее решение - это то, что шамшер Хан уже упоминал в своем ответе (+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;
    }
}
0 голосов
/ 17 мая 2018

List#removeAll удаляет все вхождений данных элементов, а не только один из каждого (в отличие от List#remove, который удаляет только первое вхождение).Так что setOfAllData содержит одну копию каждого элемента в вашем списке, а затем вы удаляете все вхождения каждого из этих элементов, а это значит, что у вас всегда будет пустой список.

Чтобы узнать, как это исправитьМне нужно знать больше о том, что вы хотите, чтобы результат был.Вы хотите удалить одну копию каждого элемента?Если это так, вы можете сделать это с:

List<BroadcastItem> allDataStoreItems  = itemsDAO.getAllItems();
Set<BroadcastItem> setOfAllData = new HashSet<>(allDataStoreItems);
setOfAllData.forEach(allDataStoreItems::remove);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...