I have a list of objects that contains two string properties.
public class A { public String a; public String b; } I want to retrieve two Sets one containing property a and one b.
The naive approach is something long these lines:
List<A> list = .... Set<String> listofa = new HashSet<>(); Set<String> listofb = new HashSet<>(); for (A item : list) { if (item.a != null) listofa.add(item.a); if (item.b != null) listofb.add(item.b); } Trying to do in a functional way in guava I ended up with this approach:
Function<String,A> getAFromList = new Function<>() { @Nullable @Override public String apply(@Nullable A input) { return input.a; } }; Function<String,A> getBFromList = Function<>() { @Nullable @Override public String apply(@Nullable A input) { return input.b; } }; FluentIterable<A> iterables = FluentIterable.from(list); Set<String> listofAs = ImmutableSet.copyOf(iterables.transform(getAFromList).filter(Predicates.notNull())); Set<String> listofBs = ImmutableSet.copyOf(iterables.transform(getBFromList).filter(Predicates.notNull())); However this way I would iterate twice over the list.
Is there any way how to avoid iterating twice or multiple times ?
In general how does one solve these uses cases in a functional way in general (not only in guava/java) ?