delmet
delmet

Reputation: 1013

Comparing an Array of Comparables in Java

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.

Upvotes: 3

Views: 2981

Answers (5)

Aither
Aither

Reputation: 1

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;
    }
}

Upvotes: 0

upasna
upasna

Reputation: 1

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);
     } 
}

Upvotes: 0

ColinD
ColinD

Reputation: 110054

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)

Upvotes: 3

Claudiu
Claudiu

Reputation: 229461

Try this:

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

Upvotes: 0

Matt Ball
Matt Ball

Reputation: 359956

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();
    }
}

Upvotes: 3

Related Questions