使用比较器比较不同的对象类型



我需要编写一个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;
  }
}

有可能总是会给出答案,但我没有在谷歌上找到合适的单词。有人建议吗?

Txs

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

有一种非常巧妙的方法可以让你使用Objectinstanceof,但如果你能实现一个公开特定接口的代理类,你最好这样做。

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

更可接受的机制是为每个实现公共接口的类实现一个代理类,然后可以使用适当的类型安全比较器对其进行比较。

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

如果您将两个不相关类型的对象存储在Set中(这让我很奇怪,因为Set通常是无序的),这意味着您使用的是原始Set,这不是很安全的类型。

您可以定义一个接口CommonAB,该接口包含用于AB的所有公共属性的getter方法。AB都将实现该接口。您将能够将AB的实例放在Set<CommonAB>中。

最后,Comparator<CommonAB>将能够比较这两种类型的对象。Comparator将仅访问接口的方法。它不在乎是比较两个A、两个B还是一个A和一个B。

相关内容

  • 没有找到相关文章

最新更新