java - 如何使用自然顺序和比较器编写函数

标签 java code-reuse

我是 Java 的新手,我正在尝试实现一种可以使用自然顺序或给定比较器参数的排序算法。

假设我有一个类似的类 C有一些自然顺序compareTo , 比较器子类 ByAltOrder , 我有一个 Comparator<C>返回新 ByAltOrder 的方法.

public class C implements Comparable<C> {
        ...                                     //fields and constructor
    public int compareTo(C that) { ... }        //natural order
    public Comparator<C> altOrder() {           //some alternative order
        return new ByAltOrder();
    }
    public class ByAltOrder implements Comparator<C>{
        public int compare(C x, C y) { ... }
    }
}

我想写一个可以使用自然顺序或替代顺序的函数。我知道如何编写一个使用自然顺序或替代顺序的函数,但我不想两次编写相同的代码,但差别很小。这可能吗?

假设我想编写一个返回非空数组最大值的函数。按照自然顺序,它看起来像这样:

public C max(C[] xs){
    res = xs[0];
    for (i = 1; i < xs.length; i++) {
        if (xs[i].compareTo(res) > 0) {
            res = points[i];
        }
    }
    return res;
}

有了 Comparator,它看起来像这样,我可以通过 x.altOrder()作为第二个参数:

public C max(C[] xs, Comparator c){
    res = xs[0];
    for (i = 1; i < xs.length; i++) {
        if (c.compare(xs[i], res) > 0) {
            res = points[i];
        }
    }
    return res;
}

但是我如何编写一个包含两者的函数呢?

编辑:我知道有一个 Arrays.sort在 Java 中,但实现 sort 或 max 只是我关于传递比较器/代码重用/java 实践的问题的玩具示例。可能是我没说清楚。

最佳答案

如果您真的想避免代码重复,则根本不应该实现该操作。

Comparator<C> altOrder = …;
C[] array = …;
C naturalMax = Collections.max(Arrays.asList(array));// natural order
C altMax     = Collections.max(Arrays.asList(array), altOrder); // alternative order

请注意,Arrays.asList 不会复制,只会包装数组,因此没有性能方面的考虑会阻止使用这些方法。

顺便说一句,ByAltOrderaltOrder() 都应该是 static,因为它们不依赖于 C

如果您想将这些方法作为练习来实现,其他答案已经指向它,请使用委托(delegate)和 Comparator.naturalOrder()

如果您没有使用 Java 8 或更新版本,则此内置比较器不可用,但您可以使用 Collections.reverseOrder(Collections.reverseOrder()) 来解决它,以获得一个比较器相同的行为,但是,当然,您应该在迁移到 Java 8 或更新版本后立即将其替换为 Comparator.naturalOrder()

关于java - 如何使用自然顺序和比较器编写函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48337036/

相关文章:

java - JDK5中的代理连接问题..UnsupportedOperationException

java - 如何将节点从 xml 文档附加到现有的 xml 文档

Java:在这种情况下我应该使用多线程吗?

java - 如何在多线程环境中共享2个SSH连接

scala - 如何重用 SBT 模块项目定义

python - 在 Pyramid 中编写应用程序,组合它们并重用它们的代码

iphone - tableview 部分标题中的选项卡式导航

java - 如何从 Java Spring 消费者应用程序调用 Java Spring 实用程序 jar

javascript - 尝试制作可重用代码,使用函数参数填充名为目标的变量区域

Android:我可以重复使用图层列表吗?