Reputation: 1013
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
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
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
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
Reputation: 229461
Try this:
if(itrNext.getClass().cast(itrNext).compareTo(l.getClass().cast(l))) {
//something
} else {
//other stuff
}
Upvotes: 0
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