user1817188
user1817188

Reputation: 517

Sort a list of generic interface

Here is the case, I have two classes A, B, and a generic interface C

Class A implements Comparable<A> {...}

interface C<T> {...}

//this class is not longer generic type, I do not know if this matter.
Class B extends A implements C<A> {...} 

Then, at other class, I got a B List and sort it as follow

List<B> list = new ArrayList<B>();
Collections.sort(list);

This works perfectly, but now I would like to change the list of B to the generic interface C, so that it can be more general.

List<C<A>> list = new ArrayList<C<A>>();
Collections.sort(list);

This time I got the Error as follow:

Bound mismatch: The generic method sort(List<T>) of type Collections is not applicable for the arguments (List<C<A>>). The inferred type C<A> is not a valid substitute for the bounded parameter <T extends Comparable<? super T>>

I have tried the following modifications (of course does not work):

  1. change C to interface C<T> extends Comparable<T>{...}
  2. change B to class B extends A implements C<A>, Comparable<T> {...}

Can anybody help me?

Upvotes: 3

Views: 3907

Answers (3)

Mark Peters
Mark Peters

Reputation: 81074

If you expect C<T> to be generically comparable based on the type it contains, you should make it comparable on itself (C<T>, not T), but bound its value type to those that implement Comparable. Something like this:

public class C<T extends Comparable<? super T>> extends Comparable<C<T>> {
    private final T value;

    @Override
    public int compareTo(C<T> that) {
       return this.value.compareTo(that.value);
    }
}

This only makes sense for some containers, such as those that simply wrap a value.

Upvotes: 1

Yogendra Singh
Yogendra Singh

Reputation: 34367

Since C<A> is not having the visibility of the Comparator defined in A hence it's complaining. Define a new comparator of C<A> as blow, it should be fine then.

List<C<A>> list = new ArrayList<C<A>>();
Collections.sort(list, new Comparator<C<A>>() {
    @Override
    public int compare(C<A> o1, C<A> o2) {
        //implement the comarison
        return 0;
    }
});

Upvotes: 1

Vikdor
Vikdor

Reputation: 24124

change C to interface C extends Comparable{...} Class B extends A implements C {...}

As you would have already seen from the error messages, these two won't work together as there will be a conflict in B's definition w.r.t to Comparable<A> and Comparable<C<A>>.

Since A is already implementing Comparable<A>, you can achieve the following

List<C<A>> list = new ArrayList<C<A>>();
Collections.sort(list);

by defining a Comparator for C<A> as follows:

class CTComparator<T> implements Comparator<C<T>>
{
    @Override
    public int compare(C<T> o1, C<T> o2)
    {
        return 0;
    }
}

and then applying the sort method with this comparator:

List<C<T>> list  = new ArrayList<C<T>>();
Collections.sort(list, comparator);

Upvotes: 2

Related Questions