Atom Feed SITE FEED   ADD TO GOOGLE READER

Coding in the small with Google Collections: Iterables.concat()

Part 7 in a Series.

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
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.