簡體   English   中英

Java中的字符串實習和HashSet

[英]String interning and HashSet in java

我已經讀過有關字符串實習的信息,其中字符串文字被重用,而使用new創建的String對象沒有被重用。 這可以當我打印在下面看到truefalse為他們的平等。 具體來說, (p1==p2)!=p3 ,所以有兩個對象,一個由p1p2指向,另一個由p3指向。 但是,當我將它們添加到HashSet ,它們都被認為是相同的。 我期望a.size()返回2 ,但是它返回1 為什么會這樣呢?

package collections;

import java.util.HashSet; 

public class Col {
    public static void main(String[] args) {
        method1();
    }

    public static void method1()
    {
        HashSet a = new HashSet();
        String p1 = "Person1";
        String p2 = "Person1";
        String p3 = new String("Person1");

        if(p1 == p2)
            System.out.println(true);
        else
            System.out.println(false);


        if(p1 == p3)
            System.out.println(true);
        else
            System.out.println(false);

        a.add(p1);
        a.add(p2);
        a.add(p3);

        System.out.println(a.size());
    }
}

產量

true
false
1

HashSet使用相等性來保留一組唯一的值,而不是標識 (即,如果兩個對象彼此equals ,但不== ,則HashSet將僅保留其中一個)。

您可以通過使用JDK的IdentityHashMap以及所有鍵之間共享的虛擬值,來實現使用身份而非相等的集合,這類似於HashSet基於HashMap

我已經讀過有關字符串實習的信息,其中字符串文字被重用,而使用new創建的String對象沒有被重用。 當我為它們的相等性打印真假時,可以在下面看到。 具體來說,(p1 == p2)!= p3,所以有兩個對象,一個由p1和p2指向,另一個由p3指向。 但是,當我將它們添加到HashSet時,都被認為是相同的。 我期望a.size()返回2,但它返回1。

僅當使用==比較String時,這才是正確的,使用equals()方法進行比較時,結果是不同的。 (有疑問,您可以測試)。

當添加到HashSet ,使用的比較方法為equals()作為適用於對象的方法。 因此, p1p2p3相等。

您可以嘗試使用equals()進行測試,它將輸出truetrue1而不是truefalse1

p1和p2是字符串文字,由於字符串池,它們指向相同的值。 因此,當我們使用==比較它們時,它們是匹配的。

p3是一個字符串對象,因此當我們使用==進行匹配時,它將嘗試使用引用進行匹配,因此它給出false。

HashSet的add方法在內部調用HashMap的put方法。 HashMap的put方法使用hashCode和equals方法在HashMap中設置值。 字符串實現hashCode和equals方法,並為相同的值提供相同的hashCode。 HashSet包含唯一值,因此它僅存儲一個值。

在這種情況下,我建議學習如何使用javap來理解代碼的編譯方式,但讓我嘗試解釋其背后的情況。

當Java編譯該類時,它將創建指令以構建該類的所謂的常量池 該常量池將保存對值為“ Person1”的字符串的引用。 編譯后的邏輯還將說p1p2的值應設置為對該字符串(它所駐留的內存中的地址)的常量池的引用。 調用p1==p2將返回true因為它們在字面上具有相同的確切值。 當您調用String p3 = new String("Person1"); 您要告訴Java在內存中的不同位置創建一個新字符串,這只是原始字符串的一個副本,然后將p3的值設置為對新字符串對象所在的內存位置的引用。因此,如果您調用p1 == p3它將返回false因為您所說的是“ p1在內存中的位置等於p2在內存中的位置嗎?”

正如其他人指出的那樣,如果調用p1.equals(p3)則它返回true因為.equals比較字符串值而不是references HashSet會看到所有相同的內容,因為它使用了.hashCode方法,該方法類似於.equals ,它從字符串值生成哈希

希望這可以消除一些困惑!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM