用比较器比较不同的对象类型
Compare different object types with comparator
我需要编写一个比较器,它采用类型 A 的对象 A 和类型 B 的对象 B。这两个对象不是公共对象的扩展。它们确实不同,但我需要通过其中的公共字段来比较这两个对象。我必须使用比较器接口,因为对象存储在 Set 中,并且在我必须使用 CollectionUtils 进行操作之后。我在谷歌上搜索了一下,我找到了 Comparator 的解决方案,但只有相同的类型。
我试图在这个方向上进行思考,但我不知道我是否走在正确的道路上。
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;
}
}
有可能总是给出答案,但我没有在Google中找到合适的词来搜索。有人有建议吗?
发送
P.S:我将两个对象添加到不同的集合中:
TreeSet<A> setA = new TreeSet<A>(myComparator);
TreeSet<B> setB = new TreeSet<B>(myComparator);
之后我会这样想:
TreeSet<??????> retain = CollectionUtils.retainAll(setA, setB);
TreeSet<??????> remove = CollectionUtils.removeAll(setA, setB);
如果您将两个不相关类型的对象存储在 Set
中(这让我感到奇怪,因为 Set
通常是无序的),这意味着您使用的是原始 Set
, 这不是很安全。
您可以为 A
和 B
的所有公共属性定义一个包含 getter 方法的接口 CommonAB
。 A
和 B
都将实现该接口。您将能够将 A
和 B
的实例放入 Set<CommonAB>
.
最后,Comparator<CommonAB>
将能够比较两种类型的对象。 Comparator
将只访问接口的方法。它不会关心它是比较两个 A、两个 B 还是一个 A 和一个 B。
有一种非常 hacky 的方法可以让您使用 Object
和 instanceof
但是如果您可以实现一个暴露特定接口的代理 class 你会更好停止这样做。
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;
}
}
更可接受的机制是为每个实现通用接口的代理实现代理 class 然后可以使用适当的类型安全比较器比较 tyhat。
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());
}
}
我需要编写一个比较器,它采用类型 A 的对象 A 和类型 B 的对象 B。这两个对象不是公共对象的扩展。它们确实不同,但我需要通过其中的公共字段来比较这两个对象。我必须使用比较器接口,因为对象存储在 Set 中,并且在我必须使用 CollectionUtils 进行操作之后。我在谷歌上搜索了一下,我找到了 Comparator 的解决方案,但只有相同的类型。
我试图在这个方向上进行思考,但我不知道我是否走在正确的道路上。
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;
}
}
有可能总是给出答案,但我没有在Google中找到合适的词来搜索。有人有建议吗?
发送
P.S:我将两个对象添加到不同的集合中:
TreeSet<A> setA = new TreeSet<A>(myComparator);
TreeSet<B> setB = new TreeSet<B>(myComparator);
之后我会这样想:
TreeSet<??????> retain = CollectionUtils.retainAll(setA, setB);
TreeSet<??????> remove = CollectionUtils.removeAll(setA, setB);
如果您将两个不相关类型的对象存储在 Set
中(这让我感到奇怪,因为 Set
通常是无序的),这意味着您使用的是原始 Set
, 这不是很安全。
您可以为 A
和 B
的所有公共属性定义一个包含 getter 方法的接口 CommonAB
。 A
和 B
都将实现该接口。您将能够将 A
和 B
的实例放入 Set<CommonAB>
.
最后,Comparator<CommonAB>
将能够比较两种类型的对象。 Comparator
将只访问接口的方法。它不会关心它是比较两个 A、两个 B 还是一个 A 和一个 B。
有一种非常 hacky 的方法可以让您使用 Object
和 instanceof
但是如果您可以实现一个暴露特定接口的代理 class 你会更好停止这样做。
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;
}
}
更可接受的机制是为每个实现通用接口的代理实现代理 class 然后可以使用适当的类型安全比较器比较 tyhat。
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());
}
}