具有可变数量的方法引用的通用对象比较方法,用于比较

Chr*_*tar 9 java generics comparator

我经常需要比较某种类型的实例以获得相等,但我不需要比较所有内容,只需要比较某些字段.我通常这样做:

Comparator<SomeType> c = Comparator.comparing(SomeType::getNumber)
  .thenComparing(SomeType::getType)
  .thenComparing(SomeType::getSite)
  .thenComparing(SomeType::getAddition)
  .thenComparing(SomeType::getImportantFlag);

if (c.compare(old, new) == 0) {
...
}
Run Code Online (Sandbox Code Playgroud)

由于我必须经常这样做,我想知道是否有一种通用的方法来做到这一点.
我必须比较的所有对象都扩展了某个基类.有没有办法编写一个静态方法,可以为我做所有这些比较?我在考虑一个静态方法,它必须要比较对象的参数和所有方法引用的vararg参数:

public static <T extends BaseType> boolean areFieldsEqual(T left, T right, whatShouldIPutHere... fields) {
}
Run Code Online (Sandbox Code Playgroud)

但我不知道如何传递方法引用以及如何在方法中的比较器中使用它们.这可以通过某种方式完成,还是应该尝试不同的方法?

Era*_*ran 3

我设法想出了一些似乎有效的方法:

public static <T extends BaseType> boolean areFieldsEqual(T left, T right, Function<T,? extends Comparable>... fields)
{
    if (fields.length < 1) {
        return true;
    }
    Comparator<T> c = Comparator.comparing(fields[0]);
    for (int i = 1; i < fields.length; i++) {
        c = c.thenComparing (fields[i]);
    }
    return c.compare(left, right) == 0;
}
Run Code Online (Sandbox Code Playgroud)

测试类:

class BaseType {
    String x;
    int y;
    public BaseType (String x, int y) {
        this.x=x;
        this.y=y;
    }
    String getX () {return x;}
    int getY () { return y;}
}

class SubType extends BaseType {
    String z;

    public SubType (String x, int y,String z) {
        super(x,y);
        this.z=z;
    }
    String getZ () {return z;}
}
Run Code Online (Sandbox Code Playgroud)

用法:

BaseType one = new BaseType("some",1);
BaseType two = new BaseType("some",2);
SubType three = new SubType("some",1,"else");
SubType four = new SubType("some",2,"else");
System.out.println (areFieldsEqual(one,two,BaseType::getX,BaseType::getY));
System.out.println (areFieldsEqual(three,four,SubType::getZ,BaseType::getX));
Run Code Online (Sandbox Code Playgroud)

输出:

false
true
Run Code Online (Sandbox Code Playgroud)