Removing an item form foreach loop that is in other foreach and use the same list

北城余情 提交于 2020-05-17 06:48:26

问题


I need to remove object from list that is in foreach that is in another foreach to not check objects with the same name (but different other values in that object).

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
    } 

of course this not working.

I was trying do something with 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
    }

but this not do the thing either... using Iterator<Foo> iterator = Iterables.cycle(fooList).iterator(); was not a good idea too.

I will be grateful for any help!


回答1:


First, @Override equals() in class Foo to decide what's the attributes that make two objects equals and one of Concurrent implementations of a list like CopyOnWriteArrayList to allow you make modification while looping over the list

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

, output

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



回答2:


If you need just to remove duplicates from the fooList by specific property, you could try this approach:

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



回答3:


Use List::removeAll

Do it as follows:

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

Make sure you use s1.equals(s2) to compare s1 with s2; rather than using s1 == s2 (the way you have done).



来源:https://stackoverflow.com/questions/61639545/removing-an-item-form-foreach-loop-that-is-in-other-foreach-and-use-the-same-lis

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!