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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28538866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 13:46:51  来源:igfitidea点击:

Compare different object types with comparator

javacollectionscompare

提问by java4fun

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.

我需要编写一个比较器,它采用类型 A 的对象 A 和类型 B 的对象 B。这两个对象不是公共对象的扩展。它们确实不同,但我需要通过其中的公共字段来比较这两个对象。我必须使用比较器接口,因为对象存储在 Set 中,并且在我必须使用 CollectionUtils 进行操作之后。我用谷歌搜索了一下,我找到了 Comparator 的解决方案,但只有相同的类型。

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:

PS:我在不同的 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);

采纳答案by OldCurmudgeon

There's a very hacky way of doing it that allows you to use Objectand instanceofbut if you can implement a proxy class that exposes a specific interface you would be better off doing that.

有一种非常hacky的方法可以让您使用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;
    }

}

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

}

回答by Eran

If you store objects of the two unrelated types in a Set(which makes me wonder, since Sets are usually unordered), this means you are using a raw Set, which is not very type safe.

如果您将两种不相关类型的对象存储在 a 中Set(这让我感到奇怪,因为Sets 通常是无序的),这意味着您使用的是 raw Set,这不是非常类型安全。

You can define an interface CommonABthat contains getter methods for all the common properties of Aand B. Both Aand Bwill implement that interface. You'll be able to put instances of Aand Bin a Set<CommonAB>.

您可以定义一个接口CommonAB,它包含的所有公共属性的getter方法AB。双方AB会实现该接口。您可以把实例AB一个Set<CommonAB>

Finally, a Comparator<CommonAB>will be able to compare objects of both types. The Comparatorwill 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.

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