3

I want to compare an array of comparables. The simplest way seems the following (details not shown):

public class ArrayComparable implements Comparable<ArrayComparable>{
ArrayList<Comparable<?>> list = new ArrayList<Comparable<?>>();

@Override
public int compareTo(ArrayComparable ac) {
    Iterator<Comparable<?>> itr = ac.list.iterator();
    for(Comparable<?> l : list) {
        Comparable<?> itrNext = itr.next();
        if(itrNext.getClass() == l.getClass()) {
            if(itrNext.compareTo(l)) {
                //something
            } else {
                //other stuff
            }
        } else {
            //some other thing
        }
    }
}

Of course the problem here is that the compareTo as in itrNext.compareTo(l) will not work giving the error: The method compareTo(capture#6-of ?) in the type Comparable<capture#6-of ?> is not applicable for the arguments (Comparable<capture#7-of ?>) which I understand why (as far as the method is concerned I might be comparing apples to oranges). On the other hand, I know I am not as I check for the class of things before comparing them.

So is there a way I can make this work? Don't worry about the sanity of comparing arrays of any comparables, as I have a good reason why I want to do that.

EDIT- SO why would I want to do something like this. Say I wanted to have an array of comparables, and I didn't care what was contained in each index, as long as the types corresponded, and they could be compared. Then I could do a general lexicographical compare between these arrays. This way I don't have to write a comparable for (int,int) and (int, string), and (string, double, string) or whatever you need. I just write one, and as long as I make sure that the types match (and I can), I am good to go.

1
  • "On the other hand, I know I am not as I check for the class of things before comparing them." So? Just because two objects are the same class doesn't mean you can compare them. Commented Mar 8, 2013 at 7:12

5 Answers 5

3

Using the raw type Comparable wherever you're currently using Comparable<?> should work. Actually, you could just do that in one place if you want:

if (((Comparable) itrNext).compareTo(l) == 0)
Sign up to request clarification or add additional context in comments.

2 Comments

Shedding the template does indeed work. It is too bad I need to live with warnings. What I wanted was not that unreasonable. But I guess this is going to be the way to go.
@delmet: Add an @SuppressWarnings("unchecked") to the method with a comment explaining why it should be safe that you're doing this.
3

Make ArrayComparable a generic class so that you can properly parameterize the generics rather than using <?> everywhere. Oh, and you might as well implement Iterable as well.

public class ArrayComparable<T> implements Comparable<ArrayComparable<T>>, Iterable<T>
{
    List<Comparable<T>> list = new ArrayList<Comparable<T>>();

    @Override
    public int compareTo(ArrayComparable<T> ac)
    {
        // snip
    }

    @Override
    public Iterator<T> iterator()
    {
        return list.iterator();
    }
}

5 Comments

I think this class (and the List by extension) contains Comparables of any type, not just a specific type T.
i suspect the OP wants the array to contain different comparables, not just of one type (i.e. he is crazy but he knows it)
If that's the case, then ew. ...oh hey, Claudiu!
Yes, I am fully aware of my insanity. But there are applications where one needs this sort of a thing. This particular one comes from hadoop.
You should restrict <T extends Comparable<? super T>> to make sure that T is comparable to itself
0

Try this:

    if(itrNext.getClass().cast(itrNext).compareTo(l.getClass().cast(l))) {
        //something
    } else {
        //other stuff
    }

Comments

0
public class GenericDemo<T>{
  T g;
 public <T extends Comparable<T>> void printData(T a[]){
    T max = a[0];
    if(a[1].compareTo(max)>0){
        max=a[1];
    }
    if(a[2].compareTo(max)>0){
    max=a[1];
    }
    System.out.println(max);
    System.out.println("DataType: " +a.getClass().getName());

      }
    public static void main(String[] ar)
    {
     Integer a[]={1,2,3};
     Byte b[]= {4,6,7};
     Short c[]={6,8,9};

     GenericDemo g = new GenericDemo();
     g.printData(a);
     g.printData(b);
     g.printData(c);
     } 
}

Comments

0

A good answer to this would be:

public final class ArrayComparable<T extends Comparable<T>>
    implements Comparable<ArrayComparable<T>> {

    private final ArrayList<T> list = new ArrayList<>();

    @Override
    public int compareTo(final ArrayComparable<T> other) {

        final Iterator<T> it = other.list.iterator();

        for (final T element : list) {
            final T otherElement = it.next();

            final int comparison = element.compareTo(otherElement);
            if (comparison < 0) {
                // something
            } else if (comparison > 0) {
                // other stuff
            } else {
                // other stuff
            }
        }
        return 0;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.