最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java各種比較對象的方式的對比總結(jié)

 更新時(shí)間:2021年06月20日 12:09:22   作者:羅漢爺  
比較對象是面向?qū)ο缶幊陶Z言的一個(gè)基本特征.在本教程中,我們將介紹Java語言的一些特性,這些特性允許我們比較對象.此外,我們還將研究外部庫中的這些特性,需要的朋友可以參考下

一、==和!=操作符

讓我們從==和!=開始可以分別判斷兩個(gè)Java對象是否相同的操作符。

1.1 原始類型(Primitives)

對于原始類型,相同意味著具有相等的值:

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

感謝自動(dòng)拆箱,在將原語值與其包裝類型對應(yīng)值進(jìn)行比較時(shí),也可以這樣做:

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

如果兩個(gè)整數(shù)的值不同,==運(yùn)算符將返回false,而!=運(yùn)算符將返回true。

1.2 對象比較

假設(shè)我們要比較兩個(gè)具有相同值的整數(shù)包裝類型:

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

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

通過比較兩個(gè)對象,這些對象的值不是1,而是它們在堆棧中的內(nèi)存地址,因?yàn)檫@兩個(gè)對象都是使用new操作符創(chuàng)建的。如果我們把a(bǔ)分配給b,我們會(huì)得到不同的結(jié)果:

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

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

現(xiàn)在,讓我們看看使用Integer#valueOf factory方法時(shí)會(huì)發(fā)生什么:

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

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

在這種情況下,它們被認(rèn)為是相同的。這是因?yàn)関alueOf()方法將整數(shù)存儲(chǔ)在緩存中,以避免創(chuàng)建太多具有相同值的包裝器對象。因此,該方法為兩個(gè)調(diào)用返回相同的整數(shù)實(shí)例。

對字符串也是一樣:

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

但是,如果它們是使用new操作符創(chuàng)建的,那么它們就不一樣了。最后,兩個(gè)空引用被認(rèn)為是相同的,而任何非空對象將被認(rèn)為與空對象不同:

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

當(dāng)然,相等運(yùn)算符的行為可能是有限的。如果我們想比較兩個(gè)映射到不同地址的對象,并根據(jù)它們的內(nèi)部狀態(tài)將它們視為相等,那該怎么辦?我們將在下一節(jié)中看到如何操作。

二、Object的equals方法

現(xiàn)在,讓我們用equals()方法討論一個(gè)更廣泛的相等概念。這個(gè)方法是在Object類中定義的,以便每個(gè)Java對象都繼承它。默認(rèn)情況下,它的實(shí)現(xiàn)比較對象內(nèi)存地址,因此它的工作方式與==運(yùn)算符相同。但是,我們可以重寫這個(gè)方法來定義相等對我們的對象意味著什么。

首先,讓我們看看它對現(xiàn)有對象(如Integer)的表現(xiàn):

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

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

當(dāng)兩個(gè)對象相同時(shí),該方法仍然返回true。我們應(yīng)該注意,我們可以傳遞一個(gè)空對象作為方法的參數(shù),但是當(dāng)然,不能作為調(diào)用方法的對象。我們可以對自己的對象使用equals()方法。假設(shè)我們有一個(gè)Person類:

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

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

我們可以重寫該類的equals()方法,以便根據(jù)兩個(gè)人的內(nèi)部詳細(xì)信息進(jìn)行比較:

@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的靜態(tài)方法equals

現(xiàn)在讓我們看看Objects的equals靜態(tài)方法。我們前面提到過,不能使用null作為第一個(gè)對象的值,否則會(huì)拋出NullPointerException。Objects助手類的equals()方法解決了這個(gè)問題。它接受兩個(gè)參數(shù)并比較它們,同時(shí)處理空值。

讓我們再次比較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();

如前所述,該方法處理空值。因此,如果兩個(gè)參數(shù)都為null,則返回true;如果只有一個(gè)參數(shù)為null,則返回false。這真的很方便。假設(shè)我們想給Person類添加一個(gè)可選的出生日期:

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的字段,它可能會(huì)變得非?;靵y。在equals()實(shí)現(xiàn)中使用Objects#equals方法更加簡潔,并且提高了可讀性:

Objects.equals(birthDate, that.birthDate);

四、Comparable接口

比較邏輯也可用于給對象排序??杀容^接口允許我們通過確定一個(gè)對象是大于、等于還是小于另一個(gè)對象來定義對象之間的順序。

Compariable接口是泛型的,只有一個(gè)方法compareTo(),該方法接受泛型類型的參數(shù)并返回int。如果當(dāng)前值小于參數(shù),則返回負(fù)值;如果它們相等,則返回0;否則返回正值。

比方說,在我們的Person類中,我們希望按Person對象的姓氏進(jìn)行比較:

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

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

如果使用姓氏大于此的人調(diào)用compareTo()方法,則返回負(fù)int;如果姓氏相同,則返回零;否則返回正int。

五、Comparator接口

Comparator接口是泛型的,并且有一個(gè)compare方法,該方法接受該泛型類型的兩個(gè)參數(shù)并返回一個(gè)整數(shù)。我們在前面的可比較接口中已經(jīng)看到了這種模式。

比較器相似;但是,它與類的定義是分離的。因此,我們可以為一個(gè)類定義任意多個(gè)比較器,其中我們只能提供一個(gè)可比較的實(shí)現(xiàn)。

假設(shè)我們有一個(gè)在網(wǎng)頁中有一個(gè)展示人信息的表格,我們想讓用戶能夠按名字而不是姓氏對他們進(jìn)行排序。如果我們還想保持當(dāng)前的實(shí)現(xiàn),那么使用Comparable是不可能的,但是我們可以實(shí)現(xiàn)自己的比較器。

讓我們創(chuàng)建一個(gè)Person Comparator,它將只根據(jù)他們的名字進(jìn)行比較:

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

現(xiàn)在讓我們用這個(gè)比較器對一組人進(jìn)行排序:

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()實(shí)現(xiàn)中,可以使用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);
}

在這種情況下,我們首先比較姓,然后比較名。然后,我們比較出生日期,但是由于它們是可空的,我們必須說明如何處理它,所以我們給出了第二個(gè)參數(shù),告訴它們應(yīng)該根據(jù)它們的自然順序進(jìn)行比較,但是空值最后才是。

六、使用Apache Commons

現(xiàn)在讓我們看看apachecommons庫。首先,讓我們導(dǎo)入Maven依賴項(xiàng):

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

6.1 ObjectUtils的notEqual方法

首先,我們來討論ObjectUtils#notEqual方法。它需要兩個(gè)對象參數(shù),根據(jù)它們自己的equals()方法實(shí)現(xiàn)來確定它們是否相等。它還處理空值。

讓我們重新使用我們的字符串示例:

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

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

應(yīng)該注意,ObjectUtils有一個(gè)equals()方法。但是,自從Java7出現(xiàn)Objects#equals之后,這種方法就被棄用了。

6.2 ObjectUtils的compare方法

現(xiàn)在,讓我們用ObjectUtils#compare方法比較對象順序。它是一個(gè)泛型方法,它接受該泛型類型的兩個(gè)可比較參數(shù)并返回一個(gè)整數(shù)。

讓我們再看看如何使用字符串:

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

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

默認(rèn)情況下,該方法通過將空值視為更大值來處理空值。它提供了一個(gè)重載版本,它提供了一個(gè)布爾參數(shù)來反轉(zhuǎn)該行為,并將它們考慮得更小。

七、使用Guava

現(xiàn)在,我們來看看Guava。Guava 是 Google 的一個(gè)開源項(xiàng)目,包含許多 Google 核心 Java 常用庫,如:集合 [collections] 、緩存 [caching] 、原生類型支持 [primitives support] 、并發(fā)庫 [concurrency libraries] 、通用注解 [common annotations] 、字符串處理 [string processing] 與 I/O 等。

首先,讓我們導(dǎo)入依賴項(xiàng):

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

7.1 Objects的equal方法

與apache commons庫類似,Google為我們提供了一種方法來確定兩個(gè)對象是否相等,objects#equal。盡管它們有不同的實(shí)現(xiàn),但它們返回相同的結(jié)果:

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

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

盡管它沒有被標(biāo)記為deprecated,但是這個(gè)方法的JavaDoc說它應(yīng)該被視為deprecated,因?yàn)閖ava7提供了Objects#equals方法。

7.2 Comparison方法

現(xiàn)在,Guava庫沒有提供一個(gè)方法來比較兩個(gè)對象(我們將在下一節(jié)中看到如何實(shí)現(xiàn)這一點(diǎn)),但它確實(shí)提供了比較原始值的方法。讓我們看看Ints helper類的compare()方法是如何工作的:

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

通常,如果第一個(gè)參數(shù)小于、等于或大于第二個(gè)參數(shù),則返回一個(gè)整數(shù),該整數(shù)可能為負(fù)、零或正。除了bytes之外,所有基元類型都有類似的方法。

7.3 ComparisonChain類

最后,Guava庫提供了ComparisonChain類,它允許我們通過一系列比較來比較兩個(gè)對象。我們可以很容易地比較兩個(gè)人的名字和姓氏:

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()方法實(shí)現(xiàn)的,因此傳遞給compare()方法的參數(shù)必須是原始類型或可比較的對象。

八、完整代碼

Java對象比較

到此這篇關(guān)于Java各種比較對象的方式的對比總結(jié)的文章就介紹到這了,更多相關(guān)Java比較對象的方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 利用Log4j將不同Package的日志輸出到不同文件的方法

    利用Log4j將不同Package的日志輸出到不同文件的方法

    日志是應(yīng)用軟件中不可缺少的部分,Apache的開源項(xiàng)目log4j是一個(gè)功能強(qiáng)大的日志組件,提供方便的日志記錄。這篇文章主要介紹了利用Log4j將不同Package的日志輸出到不同文件的方法,需要的朋友可以參考借鑒,下面來跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • IntelliJ IDEA 刷題利器 LeetCode 插件詳解

    IntelliJ IDEA 刷題利器 LeetCode 插件詳解

    這篇文章主要介紹了IntelliJ IDEA 刷題利器 LeetCode 插件,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 2020最新eclipse安裝過程及細(xì)節(jié)

    2020最新eclipse安裝過程及細(xì)節(jié)

    這篇文章主要介紹了2020最新eclipse安裝過程及細(xì)節(jié),本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java基礎(chǔ)異常處理代碼及原理解析

    Java基礎(chǔ)異常處理代碼及原理解析

    這篇文章主要介紹了java基礎(chǔ)異常處理代碼及原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • MyBatis事務(wù)原理與實(shí)戰(zhàn)深入解析

    MyBatis事務(wù)原理與實(shí)戰(zhàn)深入解析

    本文詳細(xì)解析了MyBatis事務(wù)的原理、配置與企業(yè)級(jí)實(shí)戰(zhàn)應(yīng)用,從核心基礎(chǔ)到原生JDBC事務(wù)和Spring聲明式事務(wù)的實(shí)現(xiàn),再到常見問題與解決方案,全面涵蓋了MyBatis事務(wù)的各個(gè)方面,幫助開發(fā)者深入理解并正確使用MyBatis事務(wù),感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • springboot 集成支付寶支付的示例代碼

    springboot 集成支付寶支付的示例代碼

    這篇文章主要介紹了springboot 集成支付寶支付的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • springboot整合nacos,如何讀取nacos配置文件

    springboot整合nacos,如何讀取nacos配置文件

    這篇文章主要介紹了springboot整合nacos,如何讀取nacos配置文件問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • springboot如何添加task任務(wù)執(zhí)行隊(duì)列

    springboot如何添加task任務(wù)執(zhí)行隊(duì)列

    這篇文章主要介紹了springboot如何添加task任務(wù)執(zhí)行隊(duì)列問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 關(guān)于Java?CPU或內(nèi)存使用率過高問題定位

    關(guān)于Java?CPU或內(nèi)存使用率過高問題定位

    Spring?cloud微服務(wù)廣泛應(yīng)用后,服務(wù)的監(jiān)控和運(yùn)維壓力也與日俱增,經(jīng)常有服務(wù)出現(xiàn)CPU或者內(nèi)存使用率過高的告警,那么遇到這樣的問題我們該如何排查呢?我們可以借助哪些工具來定位問題呢?本文將介紹一下遇到此類問題的解決思路和方法
    2024-10-10
  • Kotlin中?StateFlow?或?SharedFlow?的區(qū)別解析

    Kotlin中?StateFlow?或?SharedFlow?的區(qū)別解析

    Kotlin協(xié)程中的StateFlow和SharedFlow是響應(yīng)式數(shù)據(jù)流,分別用于UI狀態(tài)管理和事件通知,StateFlow有初始值,只保留最新值,適用于UI狀態(tài)管理;SharedFlow沒有初始值,可以配置緩存大小,適用于事件通知,感興趣的朋友一起看看吧
    2025-03-03

最新評論

卓资县| 扎鲁特旗| 自治县| 甘谷县| 湖北省| 五常市| 潜山县| 连平县| 商丘市| 台山市| 商丘市| 玛纳斯县| 和政县| 广汉市| 丰城市| 上饶市| 册亨县| 盖州市| 香港 | 汝南县| 南陵县| 漳浦县| 同仁县| 灌云县| 周宁县| 平武县| 全椒县| 东乡| 兰溪市| 施秉县| 来凤县| 阳山县| 芜湖县| 汉中市| 嘉黎县| 大姚县| 十堰市| 民丰县| 武穴市| 金寨县| 凌云县|