Zombieland Implementation Pattern: Double Tap
Have you seen the movie Zombieland? There are rules for surviving in Zombieland. Rule number two is called Double Tap. When a zombie is attacking you, don’t get stingy with bullets. Shoot twice!
I’ve seen the Double Tap pattern used occasionally with Eclipse Collections over the years. Here’s one example of a Double Tap.
@Test
public void doubleTapLazy()
{
ImmutableList<String> list =
Lists.immutable.with("One", "Two", "Three");
list.asLazy()
.tap(System.out::println)
.collect(String::toLowerCase)
.tap(System.out::println)
.collect(String::toUpperCase)
.forEach(System.out::println);
}
In this code, I iterate lazily over a an ImmutableList
of String
and use tap
twice. I use tap
to print out each element, and then again to print each element after it is converted to lowercase. I use the tap
method twice to see the before and after transformation state in the pipeline. Double Tap! Then I use forEach
to print out the element converted to uppercase.
The output for this code is as follows:
One
one
ONE
Two
two
TWO
Three
three
THREE
The lazy tap
method is very useful if you want to log or perform some operation with intermediate results over a series of fluent calls. The method tap
on LazyIterable
is equivalent to the method peek
on Java Stream
.
Now I will change this code to iterate eagerly by removing the call to asLazy
.
@Test
public void doubleTapEager()
{
ImmutableList<String> list =
Lists.immutable.with("One", "Two", "Three");
list.tap(System.out::println)
.collect(String::toLowerCase)
.tap(System.out::println)
.collect(String::toUpperCase)
.forEach(System.out::println);
}
The output for this code is as follows:
One
Two
Three
one
two
three
ONE
TWO
THREE
The output still contains the same number of elements, but the order of execution is different.
The method named tap
defined on the RichIterable
interface behaves like forEach
when executed eagerly on a collection like ImmutableList
. The tap
method has overrides with Covariant Return Types throughout the Eclipse Collections hierarchy returning the most specific types possible. This is why when I removed the call to asLazy
, the first call to tap
prints out all of the original elements in the list. The second call to tap
prints all of the elements converted to lowercase. Then the call to forEach
prints each element converted to uppercase with a new line after.
I include an example of a Triple Tap in the following blog when comparing Eager vs. Lazy to help folks understand the differences between the two iteration styles.
I hope this blog and the Double Tap analogy helps you understand and remember the tap
method in Eclipse Collections. Perhaps it will prove useful the next time you need to accomplish something in an intermediate series of fluent calls.
Thanks for reading!
I am the creator of and committer for the Eclipse Collections OSS project, which is managed at the Eclipse Foundation. Eclipse Collections is open for contributions.
Stackademic
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us on Twitter(X), LinkedIn, and YouTube.
- Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.