Java Top.

开始使用Spring 5和Spring Boot 2,通过学习春天课程:

>>查看课程

1.介绍

比较对象是面向对象编程语言的重要特征。

在本教程中,我们将了解Java语言的一些特性,这些特性允许我们比较对象。此外,我们将研究外部库中的这些特性。

2. ==! =运营商

让我们从==.! =操作符,可以分别判断两个Java对象是否相同。

2.1。原语

对于原始类型,相同意味着具有相等的值:

assertthat(1 == 1).istrue();

归功于自动解箱,当将原始值与其对应的包装器类型进行比较时,这也适用:

Integer a = new Integer(1);assertthat(1 == a).istrue();

如果两个整数具有不同的值,则==.运营商将返回错误的,而! =运营商将返回真的

2.2。对象

假设我们想比较两个整数包装器类型具有相同的值:

Integer a = new Integer(1);Integer b = new Integer(1);为了(a = = b) .isFalse ();

通过比较两个对象,这些对象的值不是1。而是他们堆栈中的内存地址属性创建的两个对象是不同的新的操作员。如果我们分配了一个b,然后我们会有一个不同的结果:

Integer a = new Integer(1);整数b = a;为了(a = = b) .isTrue ();

现在,让我们看看我们使用的时候会发生什么整数#返回对象的值工厂方法:

整数a = integer.valueof(1);Integer B = Integer.ValueOf(1);为了(a = = b) .isTrue ();

在这种情况下,它们被认为是相同的。这是因为返回对象的值()方法存储整数在缓存中,以避免创建具有相同值的太多包装器对象。因此,该方法返回相同的方法整数两个呼叫的实例。

Java也这样做字符串:

asserthat(“你好!”==“Hello!”)。Istrue();

但是,如果他们是使用的新的操作员,那么他们就不一样了。

最后,两个空值参考文献被认为是相同的,而任何非空值对象将被认为是不同的空值:

asserthat(null == null).istrue();assertthat(“你好!”== null).isfalse();

当然,等式运算符的行为可能会受到限制。如果我们想比较映射到不同地址的两个对象,并且根据它们的内部状态认为它们是相等的,那该怎么办呢?我们将在下一节中看到如何做到这一点。

3.对象# =方法

现在,让我们讨论一个更广泛的平等金宝搏官网188be概念等于()方法。

方法中定义的目的类使每个Java对象继承它。默认,其实现比较了对象存储器地址,因此它与其一样==.操作符。但是,我们可以覆盖此方法,以便定义对我们对象的平等手段。

首先,让我们看看它是如何对现有对象的表现整数:

Integer a = new Integer(1);Integer b = new Integer(1);Assertthat(A.Equals(B))。Istrue();

方法仍然返回真的当两个物体是相同的。

我们应该注意我们可以通过一个空值对象作为方法的参数,但当然不能作为我们调用该方法的对象。

我们可以使用等于()方法,并使用自己的对象。假设有a班级:

公共类人{私有字符串名字;私有字符串LastName;公共人(String FirstName,String LastName){this.firstname = firstname;this.lastname = lastname;}}

我们可以覆盖等于()方法,以便我们可以比较两个根据他们的内部细节:

@Override公共布尔值等于(对象O){如果(这== o)返回true;if(o == null || getClass()!= o.getClass())返回false;=(人)o;返回firstName.equals(即firstname)&& lastname.equals(chat.lastname);}

有关更多信息,请参阅我们的关于这个话题的文金宝搏官网188be章

4.对象#等于静态方法

我们现在看看对象#等于静态方法。我们之前说过我们不能用空值作为第一个对象的值,否则a空指针异常会抛出。

等于()方法的方法对象辅助阶级解决了这个问题。它需要两个参数并比较它们,也可以处理空值值。

让我们来比较一下对象又与:

新人(“乔”,“波特曼”);再次=新人物(“乔”,“波特曼”);natalie = new Person(“natalie”,“Portman”);为了(对象。=(乔,joeAgain)) .isTrue ();为了(对象。=(乔,娜塔莉)).isFalse ();

正如我们所说,方法处理空值值。因此,如果两个参数都是空值它会回归真的,如果只有其中一个是空值,它将返回错误的

这可能是非常方便的。让我们说我们想要为我们的诞生日期添加一个可选的出生日期班级:

public Person(String firstName, String lastName, LocalDate) {this(firstName, lastName);这一点。birthDate = birthDate; }

然后,我们必须更新我们的等于()方法但是空值处理。我们可以通过向我们的条件添加此条件来完成此操作等于()方法:

birthDate == null ?那birthDate == null : birthDate.equals(that.birthDate);

但是,如果我们为我们的班级添加了许多可燃的字段,它可能会变得非常凌乱。使用对象#等于我们的方法等于()实施是更清洁的,提高可读性:

对象。equals(生日、that.birthDate);

5.可比较接口

比较逻辑也可用于以特定顺序放置对象。类似的界面允许我们在对象之间定义排序,通过确定一个对象是否大于、等于或小于另一个对象。

类似的接口是通用的,只有一种方法,compareTo (),它接受泛型类型的参数并返回。如果返回的值是负数低于参数,如果它们相等,则为0,否则呈正。

让我们说,在我们的同学们,我们要比较对象的姓氏:

公共类人实现了可比的 {// ... @override public int compareto(person o){return this.lastname.compareto(o.lastname);}}

compareTo ()方法将返回负面如果被称为拥有更大的姓氏而不是,如果姓氏相同则为零,否则为正。

欲了解更多信息,请查看我们的关于这个话题的文金宝搏官网188be章

6.比较器接口

比较器界面是通用的,有一个比较方法,该方法接受该泛型的两个参数,并返回整数。我们早些时候已经看到了这种模式类似的界面。

比较器类似;但是,它与类的定义分开。所以,我们可以定义很多比较器我们想要一堂课,我们只能提供一个类似的执行。

让我们想象我们有一个在表视图中显示人员的网页,我们希望提供用户通过名字而不是姓氏对它们进行排序。它不可能类似的如果我们还想保留我们目前的实施,但我们可以实现自己的比较器

让我们创造一个比较器这只会比较他们的名字:

Comparator compareByFirstNames = Comparator.比较(Person::getFirstName);

我们现在排序列表使用那个人比较器:

新人(“乔”,“波特曼”);Person allan = new Person(" allan ", "Dale");List people = new ArrayList<>();people.add(乔);people.add (allan);people.sort (compareByFirstNames);为了(人)。containsExactly (allan,乔);

还有其他方法比较器我们可以在我们的界面使用compareTo ()实现:

@override public int compareto(person o){return comparator.comparing(person :: getlastname).thencomparing(person :: getfirstname).thencomparing(person :: getBirthdate,protoper.nullslast(protodator.natturalorder()).compare(这个,o);}

在这种情况下,我们首先比较姓氏,然后是名字。然后,我们比较出生日期,但他们必须说无效如何处理呢所以我们给出了第二个论点,告诉他们应该根据他们的自然秩序进行比较空值持续的价值观。

7. Apache Commons.

我们现在看看Apache Commons库。首先,让我们进口maven依赖:

<依赖>  org.apache.commons   Commons-Lang3   3.11  

7.1。Objectutils#Notequal.方法

首先,让我们谈谈金宝搏官网188beObjectutils#Notequal.方法。需要两个目的参数,根据自己的方式确定它们是否不等于等于()方法实现。它还处理空值值。

让我们重复使用我们的字符串例子:

String a = new String("Hello!");字符串b =新字符串(“Hello World!”);assertthat(Objectutils.notequal(a,b))。Istrue();

应当指出的是ObjectUtils有一个等于()方法。但是,自Java 7以来,这已经弃用了对象#等于出现了

7.2。ObjectUtils #比较方法

现在,让我们将对象顺序进行比较ObjectUtils #比较方法。这是一种仿制方法,需要两个类似的这种通用类型的论据并返回一个整数

让我们看看使用再次:

String first = new String("Hello!");String second = new String("How are you?");为了(ObjectUtils.compare(一、二).isNegative ();

默认情况下,该方法处理空值通过认为他们更伟大的价值观。它提供了一个重载版本,提供了反转的行为,并认为他们更少,采取一个布尔基争论。

8.番石榴

现在,让我们来看看番石榴。首先,让我们导入依赖:

<依赖>  com.google.guava   GUAVA   29.0-JRE  

8.1。对象#相等方法

类似于Apache Commons库,Google为我们提供了一种方法来确定两个对象是否相等,对象#相等。虽然它们具有不同的实现,但它们返回相同的结果:

String a = new String("Hello!");String b = new String("Hello!");为了(对象。平等(a, b)) .isTrue ();

虽然它没有被标记为弃用,但此方法的Javadoc表示,由于Java 7提供了它应该被视为已弃用对象#等于方法。

8.2。比较的方法

现在,Guava库没有提供比较两个对象的方法(我们将在下一节中看到我们可以做些什么),但是它确实为我们提供了比较原始值的方法。让我们来的整数辅助班,看看它是如何的比较()方法工作:

为了(Ints.compare(1、2).isNegative ();

像往常一样,它返回一个整数如果第一个参数小于、等于或大于第二个参数,则可以是负的、零的或正的。所有基本类型都有类似的方法,除了字节

8.3。ComparisonChain班级

最后,番石榴图书馆提供ComparisonChain允许我们通过比较链比较两个对象的类。我们可以轻松比较两个对象的名字和姓氏:

natalie = new Person(“natalie”,“Portman”);新人(“乔”,“波特曼”);int comparisonresult = comparisonchain.start().compare(natalie.getlastname(),joe.getlastname()).compare(natalie.getfirstname(),joe.getfirstname()).result();assertthat(比较事词).ispositive();

使用潜在的比较compareTo ()方法,所以将参数传递给比较()方法必须是原语或类似的年代。

9.结论

在本文中,我们研究了在Java中比较对象的不同方法。我们研究了相同、平等和有序之间的差异。我们还查看了Apache Commons和Guava库中相应的特性。

像往常一样,可以找到本文的完整代码在github上

Java底部

开始使用Spring 5和Spring Boot 2,通过学习春天课程:

>>查看课程
4注释
最老的
最新
内联反馈
查看所有评论
评论在本文上关闭!