目录
Comparable接口时用来干什么的呢?
compareTo(T)如何工作
compareTo()的灵活性
例1:通过重量排序苹果
例2:通过多个特征排序苹果
Comparable,hashCode以及Equals
结论
首页 Java java教程 Java Comparable接口的示例代码详解

Java Comparable接口的示例代码详解

Mar 20, 2017 am 11:09 AM

这篇文章是免费Java 8 课程中关于Clean Code原则的一部分。

在这篇文章中,我们要聊一聊Java Comparable接口

还有一个不错的视频可以点这里。

Comparable接口时用来干什么的呢?

我们应该如何对事物进行比较和排序?这问题听上去有点莫名其妙,但我希望你认真考虑一下。比方说,我们有一组苹果:

例1

我们要怎样对它们进行排序呢?我们希望通过重量进行排序吗?如果是的话,排序是从最轻到最重还是从最重到最轻?当我们对它们进行排序的时候,我们需要反复比较两个苹果的重量,直到正确地排好所有的苹果。苹果1比苹果2重?那它比苹果3重吗?我们需要不断比较,直到完成排序。Comparable接口可以帮助我们实现这一目标。Comparable本身不能对对象进行排序,但接口定义的方法 int compareTo(T)可以。

compareTo(T)如何工作

让我们通过使用compareTo()方法来看看哪个苹果更重,开始吧。

例2

compareTo()方法的工作原理是返回一个int值——或正,或负,或为零。它通过调用作为参数的对象来比较对象。负数表示调用的对象比参数“轻”。如果我们用大小来比较苹果,那么上面的调用会返回一个负数,例如-400,因为红苹果比青苹果小。如果两个苹果重量相等,那么调用将返回0。如果红苹果更重,那么compareTo()将返回一个正数,例如68。

compareTo()的灵活性

如果我们反复调用上面的compareTo()方法,那么我们可以通过大小来排序,这很棒,但并非故事的结束。如果我们想通过颜色来给苹果排序呢?抑或是重量?我们也可以做到。关键是,我们的客户——让我们叫他胖子农夫(见例3),需要在我们开始开发之前精确定义需要如何对苹果进行排序。

例3

他可以通过回答这两个问题来做到这一点:

  1. 他希望苹果如何进行排序?他希望我们比较什么特征?

  2. 在那样的环境中,“小于”,“等于”和“大于”指的是什么意思?

也可以使用多个特征,这个后面我们会讲。

例1:通过重量排序苹果

在第一个例子中,我们将通过重量对苹果排序。只需要一行代码。

Collections.sort(apples);
登录后复制

例4

上面的代码行可以为我们做到所有的排序工作,只要我们事先定义好如何对苹果进行排序(这就需要多行代码了)。

让我们开始写苹果类吧。

public class Apple implements Comparable {
    private String variety;
    private Color color;
    private int weight;
    @Override
    public int compareTo(Apple other) {
        if (this.weight < other.weight) {
            return -1;
        }
        if (this.weight == other.weight) {
            return 0;
        }
        return 1;
    }
}
登录后复制

例5

这是Apple类的第一个版本。由于我们使用的是compareTo方法,并且正在排序苹果,所以我实现了Comparable接口。在这第一个版本中,我们通过重量比较对象。在我们的compareTo()方法中,我们写一个if条件,说明如果这个苹果的重量小于其他的苹果,那么返回一个负数,为了保持简单,我们假定它为-1。请记住,这意味着这个苹果轻于Apple ‘other’。在第二个if语句中,我们要说明,如果苹果重量相等,那么返回一个0。当然,如果这个苹果既不是更轻,又不是一样重,那就只能比其他苹果更重了。在这种情况下,我们返回一个正数,假定为1。

例2:通过多个特征排序苹果

正如我前面提到的,我们还可以使用compareTo()比较多个特征。比方说,我们第一通过品种排序苹果,但如果两个苹果是同一品种,那么我们就按颜色排序。最后,如果这两个特性相同,那么我们将按重量排序。虽然我们可以手动实现这件事,就像我在最后一个例子中做的那样,但是其实可以用一种简洁得多的方式实现。一般来说,最好是重用现有的代码,而不是自己写。我们可以在Integer、String和枚举类中使用compareTo方法来比较值。由于我们没有使用Integer对象,用了int,所以我们不得不使用来自于Integer包装器类的一个静态的helper方法来比较两个值。

public class Apple implements Comparable {
    private String variety;
    private Color color;
    private int weight;
    @Override
    public int compareTo(Apple other) {
        int result = this.variety.compareTo(other.variety);
        if (result != 0) {
            return result;
        }
        if (result == 0) {
            result = this.color.compareTo(other.color);
        }
        if (result != 0) {
            return result;
        }
        if (result == 0) {
            result = Integer.compare(this.weight, other.weight);
        }
        return result;
    }
}
登录后复制

例6

在例6中,我们比较了客户指定的苹果的第一特性,它们的品种。如果compareTo()调用的结果为非零,那么我们返回值。否则,我们调用另一个compareTo()直到得到一个非零值,或者直到已经比较完这三个特征。尽管此代码可以工作,但它不是最有效或干净的解决方案。在例3中,我们重构我们的代码,使其更简单。

@Override
public int compareTo(Apple other) {
     int result = this.variety.compareTo(other.variety);
     if (result == 0) {
          result = this.color.compareTo(other.color);
     }
     if (result == 0) {
          result = Integer.compare(this.weight, other.weight);
     }
     return result;
}
登录后复制

例7

正如你所看到的,这大大减少了代码,并且每一次比较只要一行代码。如果一个compareTo()调用的结果是零,那么我们就转移到下一个相同if语句的比较中。顺便说一句,这是成为Clean Coder的一个很好的例子。通常情况下,你不需要立即写出干净的代码;你可以从一个粗略的想法开始,使其可以工作,然后不断改进,直到你尽可能得让它干净就可以了。

Comparable,hashCode以及Equals

你可能会注意到compareTo()看起来有点像hashCode()和equals()方法。但是,它们有一个重要的区别。对于hashCode()和equals()方法,比较个体属性的顺序不影响返回的值,但是,在compareTo()中,通过你比较对象的顺序来定义对象的顺序。

结论

在结论中我只想强调Comparable接口是多么的重要。它既用于java.util.Arrays,也用于java.util.Collections实用程序类,来排序元素和搜索排序集合中的元素。使用TreeSet和Tree Map,就更简单了——想要它们会自动排序必须实现Comparable接口的元素。

以上是Java Comparable接口的示例代码详解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

Java程序查找胶囊的体积 Java程序查找胶囊的体积 Feb 07, 2025 am 11:37 AM

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

创造未来:面向零基础的 Java 编程 创造未来:面向零基础的 Java 编程 Oct 13, 2024 pm 01:32 PM

Java是热门编程语言,适合初学者和经验丰富的开发者学习。本教程从基础概念出发,逐步深入讲解高级主题。安装Java开发工具包后,可通过创建简单的“Hello,World!”程序实践编程。理解代码后,使用命令提示符编译并运行程序,控制台上将输出“Hello,World!”。学习Java开启了编程之旅,随着掌握程度加深,可创建更复杂的应用程序。

See all articles