当提供自定义 Comparator 或元素实现 Comparable 时,在方法中拆分逻辑?

Split off logic in methods when custom Comparator is provided or elements implements Comparable?

什么是在方法中拆分逻辑的最佳实践,谁将使用 Comparable 元素,或者在创建时提供特定的 Comparator,具体取决于使用 class 的哪个构造函数? 示例:

public class MinMax<E> {

private final Comparator<? super E> comparator;
private final boolean isSpecificComparatorProvided;

public MinMax() {
    this.comparator = null;
    this.isSpecificComparatorProvided = false;
    ........;
}

public MinMax(Comparator<? super E> comparator) {
    this.comparator = comparator;
    this.isSpecificComparatorProvided = true;
    ........;
}

private boolean isBigOrEqual(E e1, E e2) {
    if (isSpecificComparatorProvided) {
        Comparator<? super E> cpr = comparator;
        int cmpr = cpr.compare(e1, e2);
        return cmpr > -1;
    } else {
        @SuppressWarnings("unchecked")
        Comparable<? super E> e1Comparable = (Comparable<? super E>) e1;
        int cmprTo = e1Comparable.compareTo(e2);
        return cmprTo > -1;
    }
}

}

我是否总是检查方法 isBigOrEqual() 中的特定比较器? 当没有提供特定的 Comparator 时,是否还需要转换为 Comparable ? 还有其他方法吗?

您可以将 E 限制为与 public class MinMax<E extends Comparable<E>> 类似,因此不再需要强制转换,因为 E 必须在编译时进行比较:

public class MinMax<E extends Comparable<E>> {

    private final Comparator<? super E> comparator;

    private final boolean isSpecificComparatorProvided;

    public MinMax() {
        this.comparator = null;
        this.isSpecificComparatorProvided = false;
    }

    public MinMax(Comparator<? super E> comparator) {
        this.comparator = comparator;
        this.isSpecificComparatorProvided = true;
    }

    private boolean isBigOrEqual(E e1, E e2) {
        if (this.isSpecificComparatorProvided) {
            return this.comparator.compare(e1, e2) > -1;
        } else {
            return e1.compareTo(e2) > -1;
        }
    }
}

在我看来,您想抽象出一种比较两个 E 类型对象的方法,并且有两个实现。一个使用特定的 Comparator,而另一个处理 Comparable 个对象。因此,您可以将这两种行为拆分为单独的 classes(实现)。

让我们从抽象概念的界面开始:

interface AbstractComparer<E> {
    public boolean isBigOrEqual(E e1, E e2);
}

抱歉这个名字没有灵感。

接下来,让我们来实现处理 Comparable 对象的案例:

class ComparableComparer<E extends Comparable<E>> implements AbstractComparer<E> {

    @Override
    public boolean isBigOrEqual(E e1, E e2) {
        return e1.compareTo(e2) > -1;
    }

}

另一种情况的实现通过构造函数接收特定比较器:

class ComparatorComparer<E> implements AbstractComparer<E> {

    private Comparator<E> comparator;

    public ComparatorComparer(Comparator<E> comparator) {
        this.comparator = comparator;
    }

    @Override
    public boolean isBigOrEqual(E e1, E e2) {
        return this.comparator.compare(e1, e2) > -1;
    }
}

现在,我们可以简化 MinMax class 并且我们可以通过构造函数提供比较方法:

public class MinMax<E> {

    private final AbstractComparer<E> comparer;

    public MinMax(AbstractComparer<E> comparer) {
        this.comparer = comparer;
    }

    private boolean isBigOrEqual(E e1, E e2) {
        return comparer.isBigOrEqual(e1, e2);
    }
}

可能最简单的处理方法是只实现 Comparator 的情况,然后当你没有通过 Comparator 时,写一个只适用于 Comparable。 (在 Java 8 中,这只是 Comparator.naturalOrder()。)

new Comparator<T> {
  @Override public int compare(T a, T b) {
    return a.compareTo(b);
  }
};

TreeMap出于性能原因不这样做,但这样做更简单。