Удаление формы элемента foreach l oop, которая находится в другом foreach, и использование того же списка - PullRequest
0 голосов
/ 06 мая 2020

Мне нужно удалить объект из списка, который находится в foreach, который находится в другом foreach, чтобы не проверять объекты с тем же именем (но другими другими значениями в этом объекте).

for (Foo foo : fooList) {
    // some code
      for (Foo foo2 : fooList){
        if (foo2.getName() == foo.getName()) {
          // some code that stores and manipulates values from foo2
          fooList.remove(foo2);
        }
      }
      //some code that using values from many foos with the same name
    } 

конечно, это не работает.

Я пытался сделать что-то с Iterator

Iterator<Foo> iterator = fooList.iterator();

while (iterator.hasNext()) {
      Foo foo = iterator.next();
      // some code
      while (iterator.hasNext()){
        Foo foo2 = iterator.next();
        if (foo2.getName() == foo.getName()) {
          // some code that stores and manipulates values from foo2
          iterator.remove();
        }
      }
      //some code that using values from many foos with the same name
    }

, но это тоже не работает ... используя Iterator<Foo> iterator = Iterables.cycle(fooList).iterator(); тоже была не очень хорошая идея.

Буду благодарен за любую помощь!

Ответы [ 3 ]

0 голосов
/ 06 мая 2020

Если вам нужно просто удалить дубликаты из свойства fooList, указав c, вы можете попробовать следующий подход:

List<Foo> foosUniqueByName = fooList.stream()
                .collect(Collectors.groupingBy(Foo::getName)) // group by name to
                .values().stream()                            // list of lists of foo
                .map(list -> list.get(0))                     // select the first foo
                .collect(Collectors.toList());                // get new list
0 голосов
/ 06 мая 2020

Используйте List :: removeAll

Сделайте это следующим образом:

List<Foo> toBeRemoveList = new ArrayList<Foo>();
for (Foo foo : fooList) {
    // some code
    for (Foo foo2 : fooList) {
        if (foo2.getName().equals(foo.getName()) && !toBeRemoveList.contains(foo2)) {
            // some code that stores and manipulates values from foo2
            toBeRemoveList.add(foo2);
        }
    }
    // some code that using values from many foos with the same name
}
fooList.removeAll(toBeRemoveList);

Убедитесь, что вы используете s1.equals(s2) для сравнения s1 с s2 ; вместо использования s1 == s2 (как вы это сделали).

0 голосов
/ 06 мая 2020

Во-первых, @Override equals() в классе Foo, чтобы решить, какие атрибуты делают два объекта равными, и одну из параллельных реализаций списка, например CopyOnWriteArrayList, чтобы вы могли вносить изменения во время цикла по списку

    static class Foo {
        int id;
        String name;

        public Foo(int id, String name) {
            this.id = id;
            this.name = name;
        }

        @Override
        public boolean equals(Object obj) {
            Foo other = (Foo) obj;
            return this.name.equals(other.name);
        }

        @Override
        public String toString() {
            return id + ", " + name;
        }
    }
    public static void main(String[] args) {
        List<Foo> list1 = new CopyOnWriteArrayList<>();
        List<Foo> list2 = new ArrayList<>();

        Foo f1 = new Foo(1, "one");
        Foo f2 = new Foo(2, "two");
        Foo f3 = new Foo(3, "three");
        Foo f4 = new Foo(4, "four");

        list1.add(f1);
        list1.add(f2);
        list1.add(f3);
        list1.add(f4);

        list2.add(f1);

        System.out.println("before remove");
        System.out.println(list1);

        for (Foo f : list1) {
            if (list2.contains(f))
                list1.remove(f);
        }

        System.out.println("after remove");
        System.out.println(list1);
    }

, вывод

before remove
[1, one, 2, two, 3, three, 4, four]
after remove
[2, two, 3, three, 4, four
...