views:

61

answers:

2

Is there any Compareable<Collection<T extends Compareable<T>>> implementation in Java (which behaves as C++'s std::list<T>::operator<() or std::set<T>::operator<())?


Edit: Comparator would make more sense...

+5  A: 

Not that I am aware of, but it shouldn't be too difficult to write.

compareTo(Collection<T> other) {
    Iterator<T> i1 = this.iterator();
    Iterator<T> i2 = other.iterator();
    while(i1.hasNext() && i2.hasNext()) {
        int c = i1.next().compareTo(i2.next());
        if(c != 0) {
            return c;
        }
    }
    if(i1.hasNext()){
        return 1;
    } else if(i2.hasNext()) {
        return -1;
    } else {
        return 0;
    }
}
ILMTitan
I should point out that this only works for ordered collections. It won't work for collections based on hash tables for example because the order of the elements returned by a hash table's iterator depends on the sequence of operations that constructed the table.
Stephen C
A: 

I don't know about those C++ operators you mention, but I'm assuming what you want is a comparator that compares the collections lexicographically.

Guava has this through its excellent Ordering class: Ordering.lexicographical()

Returns a new ordering which sorts iterables by comparing corresponding elements pairwise until a nonzero result is found; imposes "dictionary order". If the end of one iterable is reached, but not the other, the shorter iterable is considered to be less than the longer one. For example, a lexicographical natural ordering over integers considers [] < [1] < [1, 1] < [1, 2] < [2].

Say you wanted to order a List<List<String>> based on String's natural order:

List<List<String>> lists = ...; 
Ordering<Iterable<String>> comparator = Ordering.natural().lexicographical();
Collections.sort(lists, comparator);

Given that this is part of the Ordering class, you get its full power as well, including the ability to use it with any arbitrary comparator:

/*
 * This comparator will use a case insensitive comparison of individual
 * strings in determining the ordering.
 */
Ordering<Iterable<String>> comparator =
    Ordering.from(String.CASE_INSENSITIVE_ORDER).lexicographical();

/*
 * This comparator uses a Function<Foo, Long> (Foo.GET_ID) to compare the IDs
 * of Foo instances.
 */
Ordering<Iterable<Foo>> comparator = 
     Ordering.natural().onResultOf(Foo.GET_ID).lexicographical();
ColinD