Re: Collection interfaces (Was: Creating a byte[] of long size)
On 7/9/2010 4:06 PM, Daniel Pitts wrote:
It is my opinion that (given perfect hindsight), the Collections API
should have included several interfaces for comparing items, not just one.
interface Ordering<T> {
enum Order {
LESSER, EQUAL, GREATER
}
Order compare(T left, T right);
}
The only difference I see between this and Comparator<T> is
the use of the enum instead of an int. The advantages are not
immediately obvious. Meanwhile, instead of `comp(o1,o2) <= 0' one
would write `comp(o1,o2) != Order.GREATER', which reads even less
smoothly than `! (comp(o1,o2) > 0'.
interface Hasher<T> {
long hash(T value);
}
A 64-bit hashCode() would be of little use until you got to
more than 2^32 hash buckets. Just saying.
interface Equivalence<T> {
boolean equal(T left, T right);
}
I don't get it: Why not just use equals()? I guess a class
could choose not to implement Equivalence at all (and thus make
itself unusable in whatever framework relies on Equivalence), but
is that an advantage? Also, you could get a compile-time error
instead of a run-time `false' for trying to call equal() on
references of dissimilar classes; again, where's the benefit?
Then, all the appropriate Collection code could use those interfaces.
There should also be the obvious default implementations.
It might be helpful to give some examples of the "appropriate"
uses, and of the "obvious" defaults. For example, how does a HashMap
make use of a key that implements Hasher? Does it reflect on each
key its given and make a run-time choice between using hash() and
hashCode()? I don't get it ...
Not to mention that iterators should have separate methods for advancing
and retrieving,
I guess this would allow `iter.advance(666666)', with a possible
savings if the Iterator were backed by a disk file or something, where
you could just skip over two thirds of a million items without looking
at them. But, but, but!!! this only makes sense for a sequential data
structure like a List -- and for List you've already *got* access by
index without using an Iterator at all! I'm beginning to sound like a
broken record[*], I know, but what's the benefit?
and options for non-fail-fast for certain kinds of
collections (linked lists shouldn't invalidate any iterator unless the
item itself is removed).
Not so sure about that. The notion of "what's the next item?"
can certainly change if things are added or removed "near" the point
where an Iterator is active. Or, in the `iter.advance(666666)' case,
you may find yourself at an unexpected place if somebody else has
inserted 555555 items between where you are and where you're going ...
See also ListIterator.
[*] How many programmers nowadays have ever heard a broken record?
Or dialed a telephone, or seen a core? Gad, I'm feeling as old as
Methuselah.[**]
[**] Before your time, laddie, before your time.
--
Eric Sosman
esosman@ieee-dot-org.invalid