hg: lambda/collections/jdk: 2 new changesets

Thomas Münz, XDEV Software Corp. t.muenz at xdev-software.de
Wed Feb 23 05:15:09 PST 2011

If I may:
I browsed the source code a little because I'm very interested in how the JDK collections will get enhanced for functional programming, internal iteration, etc.
Background is: I wrote my own collections framework to replace the JDK collections (for many reasons of dissatisfaction with what's there, but that's not the issue here, of course)

I came accross the new Collection method
Collection<E> filter(Predicate<? super E> filter)

and it's defender delegate in SerialEagerCollections:

public static<E> Collection<E> filter(Collection<E> collection, Predicate<? super E> predicate) {
return filterTo(collection, new ArrayList<E>(), predicate);

and then accross the comment:
// Much work remains in the area of choosing the correct type of collection to construct.  

I had the exact same problem when designing the "XCollection" interfaces. I started out with the same "filter(Predicate<? super E> filter)" and ended with a very unsatisfying "new ArrayList<E>()" as an implementation detail.
To cut a long story short: as fancy as ".filter()" might look, it turned out that it is too concrete and the following is much more convenient and flexible in practice (seperating concearns more clearly):

public <C extends Collecting<? super E>> C copyTo(C target, Predicate<? super E> predicate);

(Collecting<E> is a simple interface reabstracting the boolean add(E element) method to provide more flexibility for my SQL-like Collection-querying framework. For JDK collections, one could put Collection<? super E> there as well, of course)
This way, the very same method can do the following things:

final ArrayList<Person> newPersonList = persons.copyTo(new ArrayList<Person>(), myPredicate);

final HashSet<Person> newPersonSet = persons.copyTo(new HashSet<Person>(), myPredicate);

persons.copyTo(alreadyExistingTargetCollection, myPredicate)

myCollectionFactory.toNewInstance(persons, myPredicate)

this.doSomethingElseWith(persons.copyTo(alreadyExistingTargetCollection, myPredicate));

etc. ...

In the end, I found that it's almost never desireable to have a (general purpose) collection implementation decide on its own which type of collection one has to use in the application code. The filter(predicate) variant would be just another method next to copyTo(target, predicate) to bloat method count but be of very little use (or even dangerous and thus adverse, given that the implementation-decided collection type might change silently) compared to it.

Don't know if it's bumptious (<- funny word from the translator website) to tell the "pros" how to design their interfaces ;), but back then it turned out to be cleaner architecture that way for me (although losing the fancy "filter()"-like looks :) ), so I just thought throwing it in might help.
There'd be similar findings regarding collections in general and their enhancement towards functional programming, performance, functionality, etc., but I guess I'd make myself pretty obnoxious pretty quick once getting started :-D (and it'd be off-topic here as well).


Subject: hg: lambda/collections/jdk: 2 new changesets (Tue Feb 22 16:01:45 PST 2011)
From: brian.goetz at oracle.com brian.goetz at oracle.com

> Changeset: 63693b18adef
> Author:    briangoetz
> Date:      2011-02-22 19:00 -0500
> URL:       > http://hg.openjdk.java.net/lambda/collections/jdk/rev/63693b18adef
> Add SAM types Block,Predicate,Reducer,Mapper; add simple forEach/filter/map/reduce methods to Collection,List,Set with simple serial/eager implementations; add simple test suite (1 suppressed failure)
> + defender-tests/build.xml
> + defender-tests/src/SerialEagerCollectionsTest.java
> ! make/common/shared/Defs-java.gmk
> ! make/java/java/FILES_java.gmk
> ! src/share/classes/java/util/Collection.java
> ! src/share/classes/java/util/List.java
> + src/share/classes/java/util/SerialEagerCollections.java
> ! src/share/classes/java/util/Set.java
> + src/share/classes/java/util/sam/Block.java
> + src/share/classes/java/util/sam/Mapper.java
> + src/share/classes/java/util/sam/Predicate.java
> + src/share/classes/java/util/sam/Reducer.java
> Changeset: f6dceeefc7c4
> Author:    briangoetz
> Date:      2011-02-22 19:01 -0500
> URL:       http://hg.openjdk.java.net/lambda/collections/jdk/rev/f6dceeefc7c4
> Merge

More information about the lambda-dev mailing list