java-數值,物件比較---"=="和"equals"以及自動裝箱後的比較
1.==: ==比較的是的地址
如果進行比較的兩個運算元都是數值型別,即使資料型別不一樣,只要他們的值相同,都能返回true;如97=='a',或者t==5.0;
如果兩個運算元是引用型別,那麼只有兩個引用變數的型別具有父子關係才可以比較,當指向同一個地址,即同一個物件的時候,才會返回true;
需要注意的地方1:
對於String類,當java程式直接使用如"hello"這種字串直接量(編譯時期就計算出來的字串值)時,JVM會使用常量池來管理這些字串;當使用new String("hello")的時候,JVM會先使用常量池管理"hello"直接量,再用String類的建構函式,new一個新的String物件;所以這裡會產生兩個物件,一個是編譯時存放在常量池的"hello"字串物件,一個是執行時new的String物件;
第一步,因為“hello”直接使用了雙引號宣告,故JVM會在執行時常量池中首先查詢有沒有該字串,有則進入第二步;沒有則直接在常量池中建立該字串,然後進入第二步。第二步:在常量池中建立了一個String物件之後,由於使用了new,JVM會在Heap(堆)中建立一個內容相同的String物件,然後返回堆中String物件的引用。該行程式碼分別在常量池和堆中生成了兩個內容相同的String物件。
需要注意的地方2:
public class Test1 { public static void main(String[] args) { // TODO Auto-generated method stub String s1 = "sayhello";//這裡在編譯時期就在常量池產生了一個字串常量; String s2 = "say";//這裡在編譯時期就在常量池產生了一個字串常量; String s3 = "hello";//這裡在編譯時期就在常量池產生了一個字串常量; String s4 = "say" + "hello";//編譯期間優化成一個字串,直接引用指向常量池裡已經產生的"sayhello" String s5 = s2 + s3;//s2,s3都是變數,編譯期不能確定s5是啥;用的是執行時產生在堆記憶體的s2,s3 //注意的第一點已經說過了;這裡因為常量池已經有了"sayhello",所以只產生了一個物件; String s6 = new String("sayhello"); System.out.println(s1==s4);//true,s1和s4都指向常量池的"sayhello",所以是一個物件,一個地址 System.out.println(s1==s5);//false,s1指向的是常量池裡面的"sayhello",s5指向的是執行時堆記憶體中的"sayhello"; System.out.println(s1==s6);//false,同上 } }
需要注意的地方3:
public class Test1 { public static void main(String[] args) { // TODO Auto-generated method stub String s1 = "sayhello";//這裡在編譯時期就在常量池產生了一個字串常量; final String s2 = "say";//這裡在編譯時期就在常量池產生了一個字串常量; String s3 = "hello";//這裡在編譯時期就在常量池產生了一個字串常量; String s4 = s2 + "hello";//因為s2加了final 實際也是常量, System.out.println(s1==s4);//在編譯期能夠確定;所以s4還是引用的常量池的字串常量 } }
所以記住:當用雙引號宣告的String物件會在編譯期間儲存在常量池!
需要注意的地方4:
對於Integer:
public class Test2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//首先要知道這裡是自動裝箱,在編譯期間,這裡被翻譯成Integer a1 = Integer.valueOf(10);
//然而在Integer類中,系統會把一個-128--127之間的整數自動裝箱成Integer例項,存放在一個cache陣列,
//如果以後吧一個-128--127的整數自動裝箱成一個Integer例項,會直接指向這個陣列對於的元素;如果再這個
//範圍之外系統會重新建立一個Integer例項,所以a3和a4是兩個不同的物件,而a1和a1都指向同一個陣列元素;
Integer a1 = 10;
Integer a2 = 10;
System.out.println(a1==a2);//true
Integer a3 = 128;
Integer a4 = 128;
System.out.println(a3==a4);//false
}
}
需要注意的地方5:
String str1 = new String("S") + new String("C");
System.out.println(str1.intern() == str1);
System.out.println(str1 == "SC");
true, false
String str2 = "SEUCalvin";//新加的一行程式碼,其餘不變
String str1 = new String("S")+ new String("C");
System.out.println(str1.intern() == str1);
System.out.println(str1 == "SC");
false,false;
str1.intern是去查詢常量池是否含有SC字串,如果有就返回常量池的引用,如果沒有就返回堆上的引用;所以第一段的第一個是true,第二個SC是放在常量池的,所以str1是堆上的,所以返回false;
第二段的話因為常量池上已經有了,所以str1.intern返回常量池上的,和堆上的不一樣;
2.equals:比較的是值,不過比較的規則是需要定義的;
首先,equals方法是object類的,object的equals規則是,只要兩個比較的物件地址一樣就算一樣,和==的比較規則是一樣的;
然而Integer,String等包裝類是重寫了equals方法的,他們的規則定義為只要兩個物件的值一樣,就算一樣;
所以,如果是自己定義的類,就需要重寫equals方法, 自己定義規則,否則就會繼承Object的equals方法的規則;
例題:
Consider the following code:
Integer s=new Integer(9);
Integer t=new Integer(9);
Long u=new Long(9);
Which test would return true?
1.(s==u) ,因為, s 是 Integer 型別, u 是 Long 型別,兩個不同型別的引用不能進行 == 比較。
2.(s==t) , s 是指向一個 9 的引用,而 t 也是一個指向 9 的引用,雖然都是指向 9 ,但卻是指向不同的 9 ,即是兩個不同的引用。因此 == 比較返回的是假。
3.(s.equals(t)) , Integer 的 equals 方法如下:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false ;
}
是 Integer 的例項且 value 值也相等的情況下返回真,其他返回假。在這裡, s 和 t 都是 Integer 型別且值都為 9 ,因此結果為真。
所以如果s.equals(u),型別不一樣也會返回false;
4.(s.equals(9)) , 在進行 equals 比較之前,會對 9 呼叫 Integer.valueOf 方法,進行自動裝箱 , 由於 IntegerCache 中已經存在 9 ,所以,直接返回其引用,引用相同, equals 就自然相同了。所以結果為真。
5.(s.equals( new Integer(9)) ,直接建立了一個新的 Integer 例項,但且值也為 9 ,所以,滿足條件,返回真。
相關推薦
java-數值,物件比較---"=="和"equals"以及自動裝箱後的比較
1.==: ==比較的是的地址 如果進行比較的兩個運算元都是數值型別,即使資料型別不一樣,只要他們的值相同,都能返回true;如97=='a',或者t==5.0; 如果兩個運算元是引用型別,那麼只有兩個引用變數的型別具有父子關係才可以比較,當指向同一個地址,即同一個物件的時
Java的==和equals()以及自動裝箱拆箱
char AC oid name span 兩個 也會 掌握 word 拋一個問題 大家先看下面的代碼,先不要看答案自己做一下: public class AutoboxingTest { public static void main(String[] args)
Java基本資料型別的大小,他們的封裝類以及自動拆箱和裝箱
Java提供了一套基本資料型別,總共有八種,也會有人說是有九種。 在我們的印象中,很多人可能會說出byte,short,int,long,float,double,boolean,char這八種資料型別。 那麼還有一種是哪種呢,它到底是不是資料型別呢? 我們很容易忽略一個void,有
劍指offer66題--Java實現,c++實現和python實現 12.數值的整數次方
題目描述 給定一個double型別的浮點數base和int型別的整數exponent。求base的exponent次方。 C++ /* 功能測試:base=2,exponent=32 邊界測試:base=0,exponent=-1 return base!=0,expon
程式碼塊的解釋,構造程式碼塊,靜態程式碼塊,靜態常量和常量以及靜態成員變數和物件成員變數的區別
12 程式碼塊 就是一塊程式碼,是一對大括號括起來的內容 方法中:限制變數的生命週期 類中 方法外: 構造程式碼塊:沒有關鍵字修飾,在每次建立物件時,在構造方法執行前進行執行 用途:可以對成員 變
[JAVA] List,物件引用,複製list和賦值
首先,在java中沒有C語言的指標概念,但是物件傳遞預設就是引用。 如: Person person = new Person(1,"name",23);//初始化一個person Person me = person;//新建一個Person物件me,並以person初始
java課堂筆記------toString方法和equals方法
引用類型 logs obj blog () str pre ava 當我 * 重寫toString方法 * 當我們需要使用當前類的toString方法時,通常我們 * 就需要重寫該方法。具體返回字符串的格式沒有嚴格 * 要求,可
Java之hashCode的作用和equals方法的重構規則
ide return 一點 eset log 什麽 bsp amp person 這個是博主對hashcode的初步理解,以後加深了會再來更新: 1、hashcode是什麽? hashcode是對象的散列碼,不同的對象幾乎不一樣,說幾乎是因為還是可以一樣的。 特點:每一個對
java中正確使用hashCode和equals方法
Java 中正確使用 hashCode 和 equals 方法 轉載自:[開源中國社](http://www.oschina.net/question/82993_75533) 在這篇文章中,我將告訴大家我對hashCo
同是Java開發,年薪15W和50W的到底差在哪裡?
在這個IT系統動輒就是上億流量的時代,Java作為大資料時代應用最廣泛的語言,誕生了一批又一批的新技術,包括HBase、Hadoop、MQ、Netty、SpringCloud等等 。 一些獨角獸公司以及騰訊、阿里、百度、網易等知名大廠對Java人才的需求量連年升級,有2年工作經驗的優秀程式設計師
字串,陣列,數值,物件的擴充套件
//字串 1. includes(str) : 判斷是否包含指定的字串 2. startsWith(str) : 判斷是否以指定字串開頭 3. endsWith(str) : 判斷是否以指定字串結尾 4. repeat(count) : 重複指定次數 //數值 1. 二進位制與八進位制數值表示法:
Java入門,資料型別和運算子總結
Java入門 1.所有的程式語言的最終目的都是提供一種“抽象”方法。抽象的層次越高,越接近人的思維。越接近人的思維,越容易使用。 2.越高階的語言越容易學習;當然,這隻意味著容易入門;不意味著成為高手越容易,高手仍然需要修煉。 3.Java的核心優勢:跨平臺。跨平臺是靠JVM(虛擬機器)實現的。 4.
劍指offer66題--Java實現,c++實現和python實現 15.反轉連結串列
題目描述 輸入一個連結串列,反轉連結串列後,輸出新連結串列的表頭。 C++ /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/
劍指offer66題--Java實現,c++實現和python實現 14.連結串列中倒數第k個結點
題目描述 輸入一個連結串列,輸出該連結串列中倒數第k個結點。 C++實現 /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/
劍指offer66題--Java實現,c++實現和python實現 13.調整陣列順序使奇數位於偶數前面
題目描述 輸入一個整數陣列,實現一個函式來調整該陣列中數字的順序,使得所有的奇數位於陣列的前半部分,所有的偶數位於陣列的後半部分,並保證奇數和奇數,偶數和偶數之間的相對位置不變。 C++實現 class Solution { public: void reOrderArray(v
劍指offer66題--Java實現,c++實現和python實現 11.二進位制中1的個數
題目描述 輸入一個整數,輸出該數二進位制表示中1的個數。其中負數用補碼錶示。 Python實現 # -*- coding:utf-8 -*- class Solution: def NumberOf1(self, n): cnt = 0 if n
劍指offer66題--Java實現,c++實現和python實現 29.最小的K個數
題目描述 輸入n個整數,找出其中最小的K個數。例如輸入4,5,1,6,2,7,3,8這8個數字,則最小的4個數字是1,2,3,4,。 C++ //堆排 class Solution { public: vector<int> GetLeastNumbers_Solut
劍指offer66題--Java實現,c++實現和python實現 28.陣列中出現次數超過一半的數字
題目描述 陣列中有一個數字出現的次數超過陣列長度的一半,請找出這個數字。例如輸入一個長度為9的陣列{1,2,3,2,2,2,5,4,2}。由於數字2在陣列中出現了5次,超過陣列長度的一半,因此輸出2。如果不存在則輸出0。 C++ class Solution { public:
劍指offer66題--Java實現,c++實現和python實現 27.字串的排列
題目描述 輸入一個字串,按字典序打印出該字串中字元的所有排列。例如輸入字串abc,則打印出由字元a,b,c所能排列出來的所有字串abc,acb,bac,bca,cab和cba。 C++ class Solution { public: vector<string> P
劍指offer66題--Java實現,c++實現和python實現 26.二叉搜尋樹與雙向連結串列
題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。 C++ /* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *ri