We all know the Java Collections Framework - Collection, List, Set, Map are used in almost every Java application. We also know that operator overloading in not available in Java, something that has caused a huge debate over the years, especially after C# came out and had it as a feature.
In fact, just today Daniel Pitts posted something about it under his “almost useful” tag. In that, he obviously mentions the convenient square brackets operator map[“key”] or list[1] where map is a Map instance and list is a List instance, of course.
Some history about EoD
When Java 5 came out, many ease of development (EoD in short) features were introduced. One of them was the “foreach” loop - a syntax for iterating over arrays and collections from the collections framework easily and, as an extra effect, in a standard way. This was accomplished by extracting the iteration interface out of the Collection interface, now named Iterable. Everything that implements the Iterable interface could be used in a “foreach” loop (which is, by no coincidence, the implemented interface by my Yielder class, which is a virtual collection).
It makes sense for another EoD interface to come out: the Indexer interface. This interface could be a simple interface which would allow for [ ] operators to be used through code. This shouldn’t be an issue for the operator overloading debate: The square brackets interface can hardly be used for operator abuse (with the exception of functor objects, but without the ability to have multiple parameters it would be a pretty lame usage), and if operator overloading does infiltrate the Java language, the compiler feature could be replaced with something that uses that language feature.
The details about Indexer
The Indexer interface could be as simple as:
public interface Indexer<K, V> {
void put(K key, V value);
V get(K key);
}
And now, together with the EoD compiler feature, every call such as indexer[key] = value could be compiled to indexer.put(key, value), and value = indexer[key] could be compiled to value = indexer.get(key). This shouldn’t and couldn’t be hard to do in compile time, especially seeing that the [ ] operator is currently reserved only for array instances.
This feature could obviously be used for some interesting new classes, but it would be even more relevant with current collections’ interfaces, such as Map<K, V> implements Indexer<K, V>, and perhaps the less obvious but as important List<T> implements Indexer<Integer, T>, allowing us to use collections the way they were meant to be used (and are indeed used already in many other languages).
As always, I’m interested in hearing your opinion about it!

December 5th, 2007 at 1:44 pm
You will need two interfaces, as List cannot extend Indexer (an implementation of List could, but not the interface). This isn’t a big deal - just have Indexable and Mappable.
If you would like to implement this, take a look at the Kijaro project. We are gathering together lots of proposed language changes, and an implementation really help convince those in power. Just drop me an email if you’d like to create a branch at Kijaro for this (or any other language change).
December 5th, 2007 at 7:27 pm
Are you saying it can’t because of the
get(int)defined inList, or some other reason?Also, it is unfortunate but might be necessary to create to interfaces, just to not create redundant methods (
setvs.putin List, for example).December 5th, 2007 at 7:46 pm
Due to backwards compatability, you can’t add any new methods to List (or any other JDK interface). List doesn’t have a put(K,V) or get(K) method at present, so can’t in the future.
So,
public interface Indexable {
E get(int index);
E set(int index, E newValue);
}
December 5th, 2007 at 8:21 pm
I agree with Stephen, you need at least two interfaces. I’m not sure I agree with the names he choose though.
Iterable makes sense, Indexable suggest that it can be indexed, not that it contains indexes.
It might also be useful to separate out storing from retrieving. They’re often related but not always.
IndexedGetter, IndexedSetter, KeyedGetter KeyedPutter.
December 5th, 2007 at 9:36 pm
[…] I was surprised to see that within one day of posting my previous entry on Operator Overloading, I received several comments. Avaid Ben Dov from Chaotic Java even took my idea and ran with it. Ricky Clarkson suggested using Haskels approach of allowing anything that is of the “Num” type to define +,-,/,*, etc…. I have a few things to add to this discussion. […]
December 9th, 2007 at 1:07 am
If you want to be able to retrofit Map without breaking compatibility, the get method needs to take an Object as its parameter, not a K.
December 9th, 2007 at 7:09 am
Neal: You’re right, now that I think of that. I always wondered why, when generics was added, the get method didn’t become get(K)… Doesn’t it also help type safety in a way?
December 10th, 2007 at 4:42 am
In a way, it might improve type safety, but the really get(wrongObjectType) will always return null, since the map won’t (can’t) contain that key.
My guess on why they decided to keep get(Object), was because some code may rely on that behavior (instead of having to do explicit type-checks/casting before calling get)