Freelance software grandad
software created
extended or repaired
Follow me on Mastodon
Applications, Libraries, Code
Talks & Presentations
We live now, of course, in a previously unimaginably crazy futureworld where C++ got lambdas before Java. Some time next year (and, of course, subject to our corporate overlords and their various contractual relationships) those of us nurdling around in Javaland will be able to replace those clunky anonymous classes with sleek new Java lambdas. We'll go from this
List<U> r = from(list). where(new Predicateto this{ public boolean test(T t) { ... } ). select(new Function { public U apply(T t) { ... }). toList();
List<U> r = from(list). where(t -> ...). select(u -> ...). toList();Much nicer!
In fact, if we dig a little deeper in Java 8, we can write this.
List<U> r = list.stream(). filter(t -> ...). map(u -> ...). collect(Collectors.toList());and I can chuck out my code completely. Remarkably this stuff is baked into the standard
java.util
package.
I say remarkably because the java.util
package, while undeniably java
, hasn't laboured very much on the util
. The Queue
and Deque
interfaces and their implementations, for instance, didn't arrive until Java 6. The Objects
utility methods didn't arrive until Java 7. Many of the iterfaces and classes in util
give the impression of usefulness by being maximalist - they have lots and lots of methods. Lots of methods == more utility, right? Well, no.
Consider the List
iterface, which has 23 methods. It includes a full set of methods to get, set, insert, and remove items from the list at a specific index. You almost certainly only what to perform those operations on a List
that provides O(1) random access. You almost certainly don't want to be doing that on a linked list for instance. And not only will Java let you, its library interfaces mandate that a list *must* support
There's the rather curious List.retainAll(Collection<T> coll)
method, which removes everyting from the List which isn't in the provided collection. I accept there are times when you want to this, but it's not so common you need to provide as a method on all List
implementations. Surely the more common case, given that you've gathered up the things you need into a second collection, is simply to discard the first collection? I don't see how it can be implemented remotely efficiently either. (retainAll
is not, as far as I can tell, used in the Java 7 source.)
A rather striking omission from the List
interface is sort
. That's a really, really common operation, and one that could reasonably be provided as a member method. ArrayList.sort
, for instance, could sort its backing array in place, while LinkedList.sort
would have to go rather more round the houses. Instead we have the Collections.sort
static method. It's "generic" in the sense that it works with all List
implementations and treats them all in the same way. And that way is to copy the list's contents into an array, sort the array, and then write the array's contents back into the list. (Collections.sort
is called 16 times in the Java 7 source.)
As an additional oddity, since Java 1.4 java.util
has provided the RandomAccess
marker interface to indicate that List
s support fast random access. Presumably it was introduced because somebody somewhere reviewed List
and clapped a hand to their forehead while yelling a loud "DOH". Backward compatibility ruled out changing List
and so RandomAccess
was introduced "to allow generic algorithms to alter their behaviour to provide good performance when applied to either random or sequential access lists". If you poke around in the handful of generic algorithm provided in Collections
, shuffle
for instance, rotate
, or swap
, they do all switch on RandomAccess
and act accordingly. But not sort
. Even in Java 8, the single most common List
operation copies the list, sorts the copy, then does a linear traverse to overwrite the original.
In marked contrast, the new Stream
stuff looks terrific (and I'm not just saying that because it looks virtually identical to what I wrote) and I can hope it introduces a step-change in how we use Java collections. I'd ramble on some more, but I've been up since half four this morning. Tomorrow, maybe.
Freelance software grandad
software created
extended or repaired
Follow me on Mastodon
Applications, Libraries, Code
Talks & Presentations