Reputation: 343
class A {
List<B> b;
}
class B{
boolean flag;
B(boolean flag) {
this.flag = flag;
}
//getter setter
}
B b1 = new B(true);
B b2 = new B(true);
B b3 = new B(false);
List<B> list1 = new ArrayList<>();
list1.add(b1);
list1.add(b2);
list1.add(b3);
Set<A> a = new HashSet<>();
a.add(list1);
There is a set of object A.
Object A contains a list of object B. B has a boolean property name 'flag' Using java 8 streams API, how to filter the set above such that it contains the list of B with boolean flag as true only. i.e b3 should be removed from list1. To keep it simple just added the single value.
Upvotes: 1
Views: 2769
Reputation: 137084
You have a class A
that contains a list of B
; the goal is to remove, in each A
, all the B
that matches a condition.
The first solution is make a stream of the set of A
s and map each of them to a new A
where the list of B
was filtered. Assuming that there is a constructor A(List<B> b)
and the appropriate getters (List<B> getB()
in class A
; boolean isFlag()
in class B
), you could have:
Set<A> set = new HashSet<>();
Set<A> filtered =
set.stream()
.map(a -> new A(a.getB().stream().filter(B::isFlag).collect(Collectors.toList())))
.collect(Collectors.toSet());
A second solution is possible if you can modify the list of B
s in-place, instead of creating a new one. In such a case, you could have:
set.forEach(a -> a.getB().removeIf(b -> !b.isFlag()));
which will remove all B
where the flag is false
for each A
.
Upvotes: 4
Reputation: 758
@org.junit.Test
public void test() {
B b1 = new B(true);
B b2 = new B(true);
B b3 = new B(false);
List<B> list1 = new ArrayList();
list1.add(b1);
list1.add(b2);
list1.add(b3);
Set<A> a = new HashSet();
a.add(new A(list1));
a.stream().forEach(aa -> aa.setB(aa.getB().stream().filter(B::isFlag).collect(Collectors.toList())));
System.out.println(a);
}
output:
[A{b=[B{flag=true}, B{flag=true}]}]
Upvotes: 1