AO Collections Transformers

project: current stablemanagement: productionpackaging: active
java: >= 8semantic versioning: 2.0.0license: LGPL v3

BuildMaven CentralQuality Gate StatusLines of Code
Reliability RatingSecurity RatingMaintainability RatingCoverage

Bi-directional collection transformations for Java.


  • Bi-directional transformations allow for modification of the transformed collections.
  • Support for all the major collections framework interfaces (Enumeration, ListIterator, Map, Set, SortedSet, Queue, Deque, …).
  • Small footprint, self-contained, no transitive dependencies - not part of a big monolithic package.


LEGO® were my absolute favorite as a child. I played with them for years. I brought my creations everywhere: submarine navigating the depths of the bathtub, motorized pickup truck climbing the neighbor's steep grass hill, airplane flying in the wind outside the car window, hydroplane skimming across the summer lake. They were the best.

Then I found computers. Computers were my absolute favorite. I played with them for years. I still play with them. They are the best.

Now, as a superficially responsible adult, I like to be able to compose software as I would build with LEGO®. Toward this end, we have created bi-directional collections transformations for Java. This allows the composition of collections in new ways.


For example, our specific motivation to develop this API was the desire to have a linked map with identity keys (use arbitrary objects as keys while maintaining map ordering). We could not simply combine IdentityHashMap and LinkedHashMap because they are both concrete implementations. We also could not combine IdentityKey with LinkedHashMap because that would alter the map key type to be the identity-key wrapper.

The solution is a bi-directional transformation through IdentityKey on top of LinkedHashMap. We can now add/remove objects and fully interact with the map with the identity-key wrapping performed on-the-fly behind-the-scenes:

Map<SomeKeyType, ?> map = TransformMap.of(
  new LinkedHashMap<>(),
  new FunctionalTransformer<>(