I need to write a Comparator that take an object A of type A and an object B of type B. The two object are not an extention of a common object. They are really diffferent, but I need to compare this two object by common fields in it. I have to use the comparator interface because the objects are stored in Set and after I have to do operations with CollectionUtils. I googled a little bit arround and I find solutions with Comparator but only with the same type.
I tried to implement a think in this direction but I don't know If I'm very on the correct way.
public class MyComparator implements Comparator<A>, Serializable {
private B b;
public MyComparator(B b){
this.b = b;
}
@Override
public int compare(A old, A otherOne) {
int value = 0;
if (!old.getField().equals(b.getField())) {
value = 1;
}
return value;
}
}
It's possible that an answer is always given, but I did not found the right words to search in Google. Have someone suggestions?
Txs
P.S: I add the two objects in diferent Set:
TreeSet<A> setA = new TreeSet<A>(myComparator);
TreeSet<B> setB = new TreeSet<B>(myComparator);
and after I would do thinks like this:
TreeSet<??????> retain = CollectionUtils.retainAll(setA, setB);
TreeSet<??????> remove = CollectionUtils.removeAll(setA, setB);
There's a very hacky way of doing it that allows you to use Object
and instanceof
but if you can implement a proxy class that exposes a specific interface you would be better off doing that.
class A {
public String getSomething() {
return "A";
}
}
class B {
public String getSomethingElse() {
return "B";
}
}
class C implements Comparator<Object> {
@Override
public int compare(Object o1, Object o2) {
// Which is of what type?
A a1 = o1 instanceof A ? (A) o1: null;
A a2 = o2 instanceof A ? (A) o2: null;
B b1 = o1 instanceof B ? (B) o1: null;
B b2 = o2 instanceof B ? (B) o2: null;
// Pull out their values.
String s1 = a1 != null ? a1.getSomething(): b1 != null ? b1.getSomethingElse(): null;
String s2 = a2 != null ? a2.getSomething(): b2 != null ? b2.getSomethingElse(): null;
// Compare them.
return s1 != null ? s1.compareTo(s2): 0;
}
}
The more acceptable mechanism would be to implement a proxy class for each that implements a common interface tyhat can then be compared using a proper type-safe comparator.
interface P {
public String getValue();
}
class PA implements P {
private final A a;
PA(A a) {
this.a = a;
}
@Override
public String getValue() {
return a.getSomething();
}
}
class PB implements P {
private final B b;
PB(B b) {
this.b = b;
}
@Override
public String getValue() {
return b.getSomethingElse();
}
}
class PC implements Comparator<P> {
@Override
public int compare(P o1, P o2) {
return o1.getValue().compareTo(o2.getValue());
}
}
If you store objects of the two unrelated types in a Set
(which makes me wonder, since Set
s are usually unordered), this means you are using a raw Set
, which is not very type safe.
You can define an interface CommonAB
that contains getter methods for all the common properties of A
and B
. Both A
and B
will implement that interface. You'll be able to put instances of A
and B
in a Set<CommonAB>
.
Finally, a Comparator<CommonAB>
will be able to compare objects of both types. The Comparator
will access only the methods of the interface. It won't care if it's comparing two As, two Bs or an A and a B.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With