Удаление общих элементов из двух списков пользовательских объектов - PullRequest
0 голосов
/ 10 мая 2019

В приведенном ниже коде у меня есть два списка объектов изображения (fromTagList и fromImageList). Класс изображения имеет атрибут URL изображения. В обоих списках есть общие объекты.

Моя цель состоит в том, чтобы обнаружить эти общие элементы в соответствии с их свойством URL и удалить их из обоих списков, чтобы оба списка содержали разные элементы вместе, а затем я объединю два списка в один список, чтобы этот объединенный список содержал отдельные объекты. Проблема в том, что метод, который я использовал ниже, не удалял все общие элементы, потому что я думаю, что он пропустит некоторые индексы.

for (int i = 0; i < fromTagList.size(); i++) {
    for (int k = 0; k < fromImageList.size(); k++) {
        if (fromTagList.get(i).getImageURL().equals(fromImageList.get(k).getImageURL())) {
            fromTagList.remove(i);
            fromImageList.remove(k);
        }
    }
}

Ответы [ 4 ]

1 голос
/ 10 мая 2019

.remove (index) убирает элемент, что делает список короче, но ваш индекс не учитывает это, и продолжает добавлять 1, но фактически переходит 2 элемента (+1 и удаленный).

Это работает для встроенного удаления повторяющихся элементов, но происходит сбой, когда один список содержит повторяющиеся элементы. Это работает для случая, когда внутри списка нет повторяющихся элементов, потому что я перебираю элементы задом наперед. Обратите внимание на пометку «Продолжить».

//the new ArrayList is needed so remove is supported
    List<String> fromTagList = new ArrayList(Arrays.asList(new String[] {"a", "b", "c", "1", "2", "3"}));
    List<String> fromImageList = new ArrayList(Arrays.asList(new String[] {"b", "b", "c", "d", "2", "3", "4"}));

    outer: for (int i = fromTagList.size()- 1; i >= 0; i--) {
        for (int k = fromImageList.size() - 1; k >= 0; k--) {
        System.out.println("i: " + i + " k: " + k);
        if (fromTagList.get(i).equals(fromImageList.get(k))) {
            fromTagList.remove(i);
            fromImageList.remove(k);
            continue outer;
        }
        }
    }

    System.out.println("fromTag  : " + fromTagList);
    System.out.println("fromImage: " + fromImageList);

Я не думаю, что вы можете удалить с ходу, если хотите поддерживать списки с повторяющимися элементами. Я предлагаю добавить в новый список элементов для удаления.

0 голосов
/ 10 мая 2019

Всякий раз, когда вам нужно сохранить уникальные элементы, рассмотрите возможность использования Set <>.Интерфейс set в java специально предназначен для обработки элементов uniq. Вы можете следовать приведенному ниже подходу для преобразования списков в набор:

Переопределить метод equals и hashcode для объекта изображения (используйте только атрибут url какусловие равенства и hascode).Теперь добавьте оба списка в набор.Преобразуйте набор обратно в список и вуаля!Пример:

 class ImageObj {

    String url;
    //rest of the stuff

    @Override
    public boolean equals(Object o){
    ImageObj that = (ImageObj)o;
    return that.url.equals(this.url);
    }
    @Override
    public int hascode(){
    return Objects.hascode(this.url);
    }
    }
    }

Затем -

Set<ImageObj> set= new HashSet<ImageObj>(fromTagList);
set.addAll(fromImageList);

List<ImageObj> list = new ArrayList<ImageObj>(set);

Это ваш окончательный список, который содержит все уникальные объекты.

0 голосов
/ 10 мая 2019

Да, у вас есть проблема с индексом, проблема в том, что вы удаляете что-то из списка, скажем, в позиции i = 10, элемент позиции 11 будет в 10-м, а я в 11, так что вы будете пропустите этот элемент, вторая проблема - когда вы удаляете из второго списка индексатор k, вы должны разбить, чтобы не обрабатывать все остальные элементы (если только найденный элемент не дублируется), поэтому вот мой ответ, который работает для меня после пробуем ваш код:

for (int i = 0; i < fromTagList.size(); i++) {
            for (int k = 0; k < fromImageList.size(); k++) {
                if (fromTagList.get(i).getImageURL().equals(fromImageList.get(k).getImageURL())) {
                    fromTagList.remove(i);
                    fromImageList.remove(k);
                    i--;
                    //break; this is optional
                }
            }
        }
0 голосов
/ 10 мая 2019

Я бы создал словарь.Итерация по каждому списку (отдельно).Для каждого объекта поместите его в словарь, ключом которого будет его URL.Таким образом, любой объект с таким же URL-адресом будет отображаться как одна пара ключ-значение в словаре.После добавления всего в словарь преобразуйте словарь в список.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...