iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java各种比较对象的方式的对比总结
  • 853
分享到

Java各种比较对象的方式的对比总结

2024-04-02 19:04:59 853人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

一、==和!=操作符 让我们从==和!=开始可以分别判断两个Java对象是否相同的操作符。 1.1 原始类型(Primitives) 对于原始类型,相同意味着具有相等的值: as

一、==和!=操作符

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

1.1 原始类型(Primitives)

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


assertThat(1 == 1).isTrue();

感谢自动拆箱,在将原语值与其包装类型对应值进行比较时,也可以这样做:


Integer a = new Integer(1);
assertThat(1 == a).isTrue();

如果两个整数的值不同,==运算符将返回false,而!=运算符将返回true。

1.2 对象比较

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


Integer a = new Integer(1);
Integer b = new Integer(1);

assertThat(a == b).isFalse();

通过比较两个对象,这些对象的值不是1,而是它们在堆栈中的内存地址,因为这两个对象都是使用new操作符创建的。如果我们把a分配给b,我们会得到不同的结果:


Integer a = new Integer(1);
Integer b = a;

assertThat(a == b).isTrue();

现在,让我们看看使用Integer#valueOf factory方法时会发生什么:


Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(1);

assertThat(a == b).isTrue();

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

字符串也是一样:


assertThat("Hello!" == "Hello!").isTrue();

但是,如果它们是使用new操作符创建的,那么它们就不一样了。最后,两个空引用被认为是相同的,而任何非空对象将被认为与空对象不同:


assertThat(null == null).isTrue();
assertThat("Hello!" == null).isFalse();

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

二、Object的equals方法

现在,让我们用equals()方法讨论一个更广泛的相等概念。这个方法是在Object类中定义的,以便每个Java对象都继承它。默认情况下,它的实现比较对象内存地址,因此它的工作方式与==运算符相同。但是,我们可以重写这个方法来定义相等对我们的对象意味着什么。

首先,让我们看看它对现有对象(如Integer)的表现:


Integer a = new Integer(1);
Integer b = new Integer(1);

assertThat(a.equals(b)).isTrue();

当两个对象相同时,该方法仍然返回true。我们应该注意,我们可以传递一个空对象作为方法的参数,但是当然,不能作为调用方法的对象。我们可以对自己的对象使用equals()方法。假设我们有一个Person类:


public class Person {
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }
}

我们可以重写该类的equals()方法,以便根据两个人的内部详细信息进行比较:


@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person that = (Person) o;
    return firstName.equals(that.firstName) &&
      lastName.equals(that.lastName);
}

三、Objects的静态方法equals

现在让我们看看Objects的equals静态方法。我们前面提到过,不能使用null作为第一个对象的值,否则会抛出NullPointerException。Objects助手类的equals()方法解决了这个问题。它接受两个参数并比较它们,同时处理空值。

让我们再次比较Person对象:


Person joe = new Person("Joe", "Portman");
Person joeAgain = new Person("Joe", "Portman");
Person natalie = new Person("Natalie", "Portman");

assertThat(Objects.equals(joe, joeAgain)).isTrue();
assertThat(Objects.equals(joe, natalie)).isFalse();

如前所述,该方法处理空值。因此,如果两个参数都为null,则返回true;如果只有一个参数为null,则返回false。这真的很方便。假设我们想给Person类添加一个可选的出生日期:


public Person(String firstName, String lastName, LocalDate birthDate) {
    this(firstName, lastName);
    this.birthDate = birthDate;
}

然后,我们必须更新equals()方法,但是要处理Null。我们可以将此条件添加到equals()方法中:


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

但是,如果我们在类中添加许多可为null的字段,它可能会变得非常混乱。在equals()实现中使用Objects#equals方法更加简洁,并且提高了可读性:


Objects.equals(birthDate, that.birthDate);

四、Comparable接口

比较逻辑也可用于给对象排序。可比较接口允许我们通过确定一个对象是大于、等于还是小于另一个对象来定义对象之间的顺序。

Compariable接口是泛型的,只有一个方法compareTo(),该方法接受泛型类型的参数并返回int。如果当前值小于参数,则返回负值;如果它们相等,则返回0;否则返回正值。

比方说,在我们的Person类中,我们希望按Person对象的姓氏进行比较:


public class Person implements Comparable<Person> {
    //...

    @Override
    public int compareTo(Person o) {
        return this.lastName.compareTo(o.lastName);
    }
}

如果使用姓氏大于此的人调用compareTo()方法,则返回负int;如果姓氏相同,则返回零;否则返回正int。

五、Comparator接口

Comparator接口是泛型的,并且有一个compare方法,该方法接受该泛型类型的两个参数并返回一个整数。我们在前面的可比较接口中已经看到了这种模式。

比较器相似;但是,它与类的定义是分离的。因此,我们可以为一个类定义任意多个比较器,其中我们只能提供一个可比较的实现。

假设我们有一个在网页中有一个展示人信息的表格,我们想让用户能够按名字而不是姓氏对他们进行排序。如果我们还想保持当前的实现,那么使用Comparable是不可能的,但是我们可以实现自己的比较器。

让我们创建一个Person Comparator,它将只根据他们的名字进行比较:


Comparator<Person> compareByFirstNames = Comparator.comparing(Person::getFirstName);

现在让我们用这个比较器对一组人进行排序:


Person joe = new Person("Joe", "Portman");
Person allan = new Person("Allan", "Dale");

List<Person> people = new ArrayList<>();
people.add(joe);
people.add(allan);

people.sort(compareByFirstNames);

assertThat(people).containsExactly(allan, joe);

在compareTo()实现中,可以使用Comparator接口上的其他方法:


@Override
public int compareTo(Person o) {
    return Comparator.comparing(Person::getLastName)
      .thenComparing(Person::getFirstName)
      .thenComparing(Person::getBirthDate, Comparator.nullsLast(Comparator.naturalOrder()))
      .compare(this, o);
}

在这种情况下,我们首先比较姓,然后比较名。然后,我们比较出生日期,但是由于它们是可空的,我们必须说明如何处理它,所以我们给出了第二个参数,告诉它们应该根据它们的自然顺序进行比较,但是空值最后才是。

六、使用Apache Commons

现在让我们看看apachecommons库。首先,让我们导入Maven依赖项:


<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

6.1 ObjectUtils的notEqual方法

首先,我们来讨论ObjectUtils#notEqual方法。它需要两个对象参数,根据它们自己的equals()方法实现来确定它们是否相等。它还处理空值。

让我们重新使用我们的字符串示例:


String a = new String("Hello!");
String b = new String("Hello World!");

assertThat(ObjectUtils.notEqual(a, b)).isTrue();

应该注意,ObjectUtils有一个equals()方法。但是,自从Java7出现Objects#equals之后,这种方法就被弃用了。

6.2 ObjectUtils的compare方法

现在,让我们用ObjectUtils#compare方法比较对象顺序。它是一个泛型方法,它接受该泛型类型的两个可比较参数并返回一个整数。

让我们再看看如何使用字符串:


String first = new String("Hello!");
String second = new String("How are you?");

assertThat(ObjectUtils.compare(first, second)).isNegative();

默认情况下,该方法通过将空值视为更大值来处理空值。它提供了一个重载版本,它提供了一个布尔参数来反转该行为,并将它们考虑得更小。

七、使用Guava

现在,我们来看看Guava。Guava 是 Google 的一个开源项目,包含许多 Google 核心 Java 常用库,如:集合 [collections] 、缓存 [caching] 、原生类型支持 [primitives support] 、并发库 [concurrency libraries] 、通用注解 [common annotations] 、字符串处理 [string processing] 与 I/O 等。

首先,让我们导入依赖项:


<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>29.0-jre</version>
</dependency>

7.1 Objects的equal方法

与apache commons库类似,Google为我们提供了一种方法来确定两个对象是否相等,objects#equal。尽管它们有不同的实现,但它们返回相同的结果:


String a = new String("Hello!");
String b = new String("Hello!");

assertThat(Objects.equal(a, b)).isTrue();

尽管它没有被标记为deprecated,但是这个方法的JavaDoc说它应该被视为deprecated,因为java7提供了Objects#equals方法。

7.2 Comparison方法

现在,Guava库没有提供一个方法来比较两个对象(我们将在下一节中看到如何实现这一点),但它确实提供了比较原始值的方法。让我们看看Ints helper类的compare()方法是如何工作的:


assertThat(Ints.compare(1, 2)).isNegative();

通常,如果第一个参数小于、等于或大于第二个参数,则返回一个整数,该整数可能为负、零或正。除了bytes之外,所有基元类型都有类似的方法。

7.3 ComparisonChain类

最后,Guava库提供了ComparisonChain类,它允许我们通过一系列比较来比较两个对象。我们可以很容易地比较两个人的名字和姓氏:


Person natalie = new Person("Natalie", "Portman");
Person joe = new Person("Joe", "Portman");

int comparisonResult = ComparisonChain.start()
  .compare(natalie.getLastName(), joe.getLastName())
  .compare(natalie.getFirstName(), joe.getFirstName())
  .result();

assertThat(comparisonResult).isPositive();

底层比较是使用compareTo()方法实现的,因此传递给compare()方法的参数必须是原始类型或可比较的对象。

八、完整代码

Java对象比较

到此这篇关于Java各种比较对象的方式的对比总结的文章就介绍到这了,更多相关Java比较对象的方式内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java各种比较对象的方式的对比总结

本文链接: https://www.lsjlt.com/news/128618.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java各种比较对象的方式的对比总结
    一、==和!=操作符 让我们从==和!=开始可以分别判断两个Java对象是否相同的操作符。 1.1 原始类型(Primitives) 对于原始类型,相同意味着具有相等的值: as...
    99+
    2022-11-12
  • java中各种对象的比较方法
    目录前言1. 问题提出2. 元素的比较2.1 基本类型的比较2.2 对象的比较3. 对象的比较3.1 覆写基类的equal3.2 基于Comparble接口类的比较3.3 基于比较器...
    99+
    2023-05-18
    java对象比较方法 js 对象比较 java对象的比较
  • 比较JavaScript对象的四种方式
    目录前言引用比较手动比较浅层比较深层比较总结前言 比较JavaScript中的原始值非常简单。只需使用任何一种可用的相等运算符即可,例如严格相等运算符: 'a' === 'c';...
    99+
    2022-11-12
  • Java Integer对象的比较方式
    目录Java Integer对象的比较自动装箱自动拆箱Integer初始化Integer对象之间的比较Integer类型变量比较问题代码1代码2代码3代码4关于这种现象,查了下资料,...
    99+
    2022-11-12
  • java对象的比较
    java对象的比较 🐱1. 问题提出🐱🐶2. 元素的比较🐶2.1 基本类型的比较2.2 对象的比较 🐭 3....
    99+
    2023-08-31
    java 算法 数据结构
  • JavaScript 对象的四种方式比较详解
    目录前言1. 引用比较2. 手动比较3. 浅层比较4. 深层比较5. 总结前言 比较 JavaScript 中的值非常简单,只需用相等运算符即可,例如严格相等运算符: 'a' ===...
    99+
    2022-11-13
  • Java数据结构之对象的比较
    目录元素比较基本类型的比较对象的比较对象如何进行比较覆写基类的equal基于Comparble接口类的比较基于比较器的比较集合框架中PriorityQueue(优先级队列)的比较方式...
    99+
    2022-11-13
  • 浅谈java对象的比较
    目录1、元素的比较2、类的比较3、比较方法3.1 重写equals方法3.2 基于Comparble接口类的比较3.3 基于比较器比较基于比较器比较:Comparator接口3.4 ...
    99+
    2022-11-12
  • 【数据结构Java版】对象的比较之Comparable与Comparator比较器
    目录   一、基本类型的比较 二、对象类型的比较 (1)对象类型比较出现的问题 (2)重写基类equals方法 (3)基于Comparable接口的比较 1.实现Comparable接口,重写compareTo方法 (4)基于Compara...
    99+
    2023-09-06
    数据结构 比较 Comparable Comparator 算法
  • 比较JavaScript 对象的四种方式分别是怎样的
    比较JavaScript 对象的四种方式分别是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 比较 JavaS...
    99+
    2022-10-19
  • JavaScript函数的性能各种方式对比
    这篇文章主要介绍了JavaScript函数的性能各种方式对比,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。JavaScript是什么JavaScript是一种直译式的脚本语言...
    99+
    2023-06-14
  • MyBatis批量插入的三种方式比较总结
    前言 数据库使用的是SQLServer,JDK版本1.8,运行在SpringBoot环境下 对比3种可用的方式 反复执行单条插入语句 xml拼接sql 批处...
    99+
    2022-11-12
  • 6种Java创建对象的方式总结
    目录1. 使用new关键字2. 使用Class的newInstance()方法3. 使用Constructor的newInstance()方法4. 使用clone()方法5. 使用反...
    99+
    2023-05-18
    Java创建对象方式 Java创建对象
  • Java比较两个对象大小的三种方法详解
    目录一. 为什么需要比较对象二. 元素的比较1. 基本类型的比较 2. 引用类型的比较 三. 对象比较的方法1. equals方法比较2. 基于Comparabl...
    99+
    2022-11-13
  • java集合遍历的几种方式总结及详细比较
    集合类的通用遍历方式, 用迭代器迭代:Iterator it = list.iterator();while(it.hasNext()) {  Object obj = it.next();}...
    99+
    2023-05-31
    java 集合 遍历
  • 详解java关于对象的比较
    目录同类型对象的比较样例引入相等性判断总结同类型对象的比较 三个维度去比较 同一性 相等性 相似性 样例引入 想象一下这样的一个场景:小王去图书馆借了一本java核心技术卷1,如图 ...
    99+
    2022-11-12
  • redis存储对象方法的比较
    本篇内容主要讲解“redis存储对象方法的比较”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“redis存储对象方法的比较”吧!redis 存储对象的方法对比问题背景:原来项目里面全部是直接red...
    99+
    2023-06-20
  • .NET中创建对象的几种方式和对比
    目录使用标准反射的 Invoke 方法使用 Activator.CreateInstance 使用 Microsoft.Extensions.DependencyInjection ...
    99+
    2022-11-12
  • Java中对象比较的示例分析
    这篇文章主要介绍了Java中对象比较的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。元素比较基本类型的比较在Java中,基本类型的对象可以直接比较大小public&n...
    99+
    2023-06-29
  • Mybatis批量插入数据的两种方式总结与对比
    目录总体描述方式一:拼接插入多条数据的SQLmapper接口代码XML文件配置方式二: 使用Batch Insert技术Mapper接口代码XML文件配置应用层代码对比分析性能对比应...
    99+
    2023-01-30
    mybatis大批量数据导入 Mybatis大量数据入库 mybatis批量添加数据
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作