views:

240

answers:

3

I've stumbled upon a bug in the Java Collections API, in Collections.java.

Here’s the code verbatim from the JDK’s source. Just so you know, the JavaDoc version tag reads "1.106, 04/21/06". The method is located in line 638.

public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
    Iterator<? extends T> i = coll.iterator();
    T candidate = i.next();

    while (i.hasNext()) {
        T next = i.next();
        if (next.compareTo(candidate) > 0)
            candidate = next;
    }
    return candidate;
}

If you take a second to analyse the method, you’ll quickly spot the bug: T candidate = i.next(). D’oh! Calling i.next() on an Iterator without checking hasNext() first? That’s just asking for an exception.

Surely something like that should've been spotted during coding? It means use of the API must check if the collection has at least two elements.

+13  A: 

No - it means that it's invalid to try to find the maximal element of an empty collection. This is specified in the API docs:

Throws:
    NoSuchElementException - if the collection is empty.

That's what Iterator.next() is documented to throw if there's no next element, so it's doing exactly what it's meant to.

Note that after the first call to next(), there's a call to hasNext() to check whether there's more than one element.

Jon Skeet
C'mon, isn't it your bedtime yet? I was just in the middle of saying the same thing.
Michael Myers
surely for a one-element collection, the correct operation is that it should return that element, not throw an exception.
Beau Martínez
It does return that element.
erickson
c'est vrais. i overlooked the while block; something else had caused the excepiton i'd assume.
Beau Martínez
my answer got Skeeted :(
Steve Reed
@Steeve Reed You are no match for this 32 year - married and father of 3 -google employee - C# book writer guy from Reading, Britain.
Tom
+6  A: 

Hard to call it a bug since the exception is documented here

Throws:

  • ClassCastException if the collection contains elements that are not mutually comparable (for example, strings and integers).
  • NoSuchElementException if the collection is empty.
Steve Reed
+1  A: 

According to API doc Collection.max method throws NoSuchElementException if collection is empty - this is exactly what you observed.

grigory