Iterables.concat() combines multiple iterables (such as ArrayList and HashSet) so you can go through multiple collections' elements in a single pass:
Before:
public boolean orderContains(Product product) {
List<LineItem> allLineItems = new ArrayList<LineItem>();
allLineItems.addAll(getPurchasedItems());
allLineItems.addAll(getFreeItems());
for (LineItem lineItem : allLineItems) {
if (lineItem.getProduct() == product) {
return true;
}
}
return false;
}After:
public boolean orderContains(Product product) {
for (LineItem lineItem : Iterables.concat(getPurchasedItems(), getFreeItems())) {
if (lineItem.getProduct() == product) {
return true;
}
}
return false;
}If ever you only have the Iterator and not the Iterable, the equivalent method is Iterators.concat. As a special treat, both concat methods are optimized so that they don't need a private collection.
Part 8

3 comments:
I see that Iterables has both
concat(Iterable<? extends T>... inputs)
and
concat(Iterable<? extends T> a, Iterable<? extends T> b)
What's the rationale for having the second function, since the first function would cover the two-Iterable case just fine?
varargs & generics are not friends. the 2-arg version lets you concatenate two Lists of Callable<String>s without suppressing a warning.
Thanks for the explanation. I see the warning, now:
Type safety : A generic array of Iterable<? extends Integer> is created for a varargs parameter.
And, to be clear: that warning appears for all n != 2; n == 2 is just a particularly common case, so by having a special function for that, we avoid the warning in most code.
Post a Comment