Java двойная ловушка для цикла, все еще возвращающего дубликаты - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть метод, предназначенный для удаления дублирующихся объектов из ArrayList.Объекты имеют пользовательский класс IndividualEntry, и метод выглядит следующим образом:

 private static ArrayList<IndividualEntry> cleanList(ArrayList<IndividualEntry> inputList){
        ArrayList<IndividualEntry> thisList = inputList;
        IndividualEntry thisEntry;
        IndividualEntry thatEntry;
        for(int i = 0; i<thisList.size();i++){
            thisEntry = thisList.get(i);
            System.out.println("First entry is "+thisEntry);
        for(int j = (i+1); j<thisList.size(); j++){
            thatEntry = thisList.get(j);
            System.out.println("Second entry is "+thatEntry);
            if(thisEntry.equals(thatEntry)){
                thisList.remove(thatEntry);
            System.out.println("Entry removed: "+thatEntry);
            }
        }
            }
        return thisList;
    }

Метод успешно удаляет НЕКОТОРЫЕ дубликаты.ArrayList перед запуском этого метода выглядит следующим образом (каждая буква представляет уникальный объект):

ABBCABBAABBBBC

После запуска метода он выглядит следующим образом:

CABBBC

Я не понимаю, почему этот метод будет переупорядочивать результаты и по-прежнему включать дубликаты, но я подозреваю, что это происходит из-за изменения thisList во внутреннем цикле for, но в целом цикл for по-прежнему использует оригинальныйзначение thisList.Это верно?Что бы исправить это?

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Используя java 8+, вы можете сделать следующее, чтобы удалить дубликаты:

private static List<String> cleanList(List<String> inputList){
    return inputList.stream().distinct().collect(Collectors.toList());
}

Это создаст поток из List, примет только уникальные значения, а затем соберет их в List

0 голосов
/ 14 ноября 2018

, удаляя элемент из списка и перебирая его, вы ломаете логику. Вы не получаете явного явного сбоя, как если бы вы получали итераторы, но, так как циклы не учитывают удаленные элементы, вы просто пропускаете элементы.

Гораздо проще было бы использовать JDK LinkedHashSet, который одновременно гарантирует один экземпляр каждого значения и сохраняет порядок вставки:

private static ist<IndividualEntry> cleanList(List<IndividualEntry> inputList) {
    return new ArrayList<>(new LinkedHashSet<>(inputList));
}

Это, конечно, предполагает, что ваш класс IndividualEntry правильно реализует методы equals(Object) и hashCode().

...