Apache CollectionUtils transformedCollection caveat
PDFI love the (now aging) Apache collections15 library, but here’s a small ugly detail that is good to know.
The following call doesn’t do what you would think it does – or what I thought it would do anyway (and the JavaDoc isn’t clear enough):
1 | Collection<Cube> ballsAsCubes = CollectionUtils.transformedCollection(myBalls, new BallToCubeTransformer()); |
This does not transform your collection of balls into a collection of cubes. It does transform balls you add afterwards but not what is already in there. So what happens is that when you pass in a populated list with balls, the Collection<Cube> will contain objects of type Ball in runtime! That’s right, the CollectionUtils library suppresses any generics warnings so that you will get a nice runtime exception when you use it to, say, sort the list:
1 2 3 4 5 6 | java.lang.ClassCastException: org.codemonkey.Ball at org.codemonkey.CubeComparator.compare(CubeComparator.java:1) at java.util.Collections$ReverseComparator2.compare(Collections.java:3361) at java.util.Arrays.mergeSort(Arrays.java:1284) at java.util.Arrays.sort(Arrays.java:1223) at java.util.Collections.sort(Collections.java:159) |
In fact, the TransformedCollection
that comes out CollectionUtils.transformedCollection()
is rather the odd one out, as you actually need to cast the list to the raw type (or TransformedCollection
) in order to add a cube which is then transformed to a ball. either way the compiler will warn you about your foul language. From the TransformedCollection
documentation:
1 2 3 4 5 6 7 | above package comment: // GenericsNote: Converted, but unfortunately very little type-safety could be achieved without breaking Collection interface. in class comment: /** * Note: This class cannot support generics without breaking the Collection contract. */ |
Fun isn’t it.
What you should do instead is the following:
1 | Collection<Cube> ballsAsCubes = CollectionUtils.collect(myBalls, new BallToCubeTransformer()); |
Almost the same… almost, but not quite.
Tags: java
ykzhao
Hi…how to as3wavsound play 16Khz sound? thank you
Dima
Ok, it adds a runtime transformer calls to the objects being put to newly created collection. What i cannot understand is why are they decided to leave the untransformed objects in it??? It made it unusable.
Thanks for the posting though. I was starting to think that it is me who crazy is =)