In computer science, zipping translates sequences into sequences where, if visualized in two dimensions, the rows and columns are swapped. So the zip of:

[['a', 'b', 'c'],
 [ 1 ,  2 ,  3 ]]

would be:

[['a', 1],
 ['b', 2],
 ['c', 3]]

It's a very handy operation and depending on the language, may be supported for tuples, lists, streams and other sequences or aggregates.

Java collections and streams don't currently support such functionality out-of-the-box with various workarounds discussed here. The summary: language and library design is hard; any zip implementation that Java provides would have some limitations baked in, so they instead provide the necessary primitives to allow folks to build their own implementations based on their specific requirements.

We'll look at what Groovy provides and some of the available Java libraries that you can also use. The same caveats apply to these libraries, each will have its own implementation strengths and weaknesses.

We'll use an example inspired by this Donald Raab blog post. It looks at zipping (and formatting) lists of strings containing "fall"-inspired emoji. Yes, it's late spring for the southern hemisphere who also mostly call fall "autumn", but hopefully everyone will appreciate the inspiration.


fall.png


Groovy

Groovy uses the transpose method for zipping:

ZippingCollectionsGroovy.png

Eclipse Collections

Eclipse Collections has a zip method on its list classes:

ZippingCollectionsEC.png

Guava

Guava has a streams utility class with a zip method:

ZippingCollectionsGuava.png

StreamEx

StreamEx provides an enhanced stream library which supports zipWith:

ZippingCollectionsStreamEx.png

Vavr

Vavr has a zipWith method on its list class:

ZippingCollectionsVavr.png

jOOλ

jOOλ has a zip method for its sequences:

ZippingCollectionsJool.png

Groovy GQuery

If you are a fan of query-like DSLs, Groovy's language integrated query, gquery, can also be used:

ZippingCollectionsGQ.png

This uses a special _rn "row number" pre-defined variable in GQ expressions. It follows the same strategy as the IntStream "workaround" for Java mentioned in this blog.

More information

  • The code examples can be found in the repo