collectionsjava-8java-7guavaapache-commons-collection

Collection intermediate operations library in Java7


I Like the idea of intermediate operations of Java8, Where all operations will applied once when a terminal operation is reached.

I am asking is there library that I can use with Java 7 that allow me to achieve such behaviour.

Note:
I am using commons-collections4 for collection operations, like forAllDo, So it is possible to use it for such case? (intermediate vs terminal operations)


Solution

  • Guava

    As your [Guava] tag suggests, most Guava collection operations are lazy - they are applied only once needed. For example:

    List<String> strings = Lists.newArrayList("1", "2", "3");
    List<Integer> integers = Lists.transform(strings, new Function<String, Integer>() {
        @Override
        public Integer apply(String input) {
            System.out.println(input);
            return Integer.valueOf(input);
        }
    });
    

    This code seems to convert a List<String> to a List<Integer> while also writing the strings to the output. But if you actually run it, it doesn't do anything. Let's add some more code:

    for (Integer i : integers) {
        // nothing to do
    }
    

    Now it writes the inputs out!

    That's because the Lists.transform() method doesn't actually do the transforming, but returns a specially crafted class which only computes the values when they are needed.

    Bonus proof that it all works nicely: If we removed the empty loop and replaced it with e.g. just integers.get(1);, it would actually only output the number 2.

    If you'd like to chain multiple methods together, there is always FluentIterable. That basically allows you to code in the Java 8 Stream-like style.


    Goldman Sachs Collections

    While Guava usually does the right thing by default and works with JDK classes, sometimes you need something more complex. That's where Goldman Sachs collections come in. GS collections give you far more flexibility and power by having a complete drop-in collections framework with everything you might dream of. Laziness is not theer by default, but can be easily achieved:

    FastList<String> strings = FastList.newListWith("1", "2", "3");
    LazyIterable<Integer> integers = strings.asLazy().collect(new Function<String, Integer>() {
        @Override
        public Integer valueOf(String string) {
            System.out.println(string);
            return Integer.valueOf(string);
        }
    });
    

    Again, doesn't do anything. But:

    for (Integer i : integers) {
        // nothing to do
    }
    

    suddenly outputs everything.