1. 程式人生 > >Java中字串比較的一道面試題

Java中字串比較的一道面試題

題目:

public class Test {

    public static void main(String[] args) {
        String a = "hello";  
        String b = "hello";
        String c = a + b;
        String d = a + "hello";
        String e = a + b;

        System.out.println(a == b);   
        System.out.println(a == c);
        System.out
.println(c == d); System.out.println(c == e); } }

輸出結果:

true
false
false
false

解析:直接把上面程式碼進行反編譯一下就知道其中的原理了。

這裡寫圖片描述

從上面可以看到字元的的加操作其實是建立了一個StringBuilder物件,第一個字串作為初始化引數傳入StringBuilder物件,第二個引數使用StringBuilder的append操作新增到StringBuilder,這樣就完成了加操作,所以新得到的物件是創建出來的一個新的StringBuilder物件,它存放在堆中,所以從上面看到c和e是不同的原因就是它們是新創建出來的兩個不同的物件。a跟b相同的原因就是因為字面量字串”hello”存放在常量區,它們兩個都指向的是同一個字串。

上面可以進行如下理解:

String a = "hello";  
String b = "hello";

String tmp = String.valueOf(a);
StringBuilder sb = new StringBuilder(tmp);
sb.append(b);
String c = sb.toString();

String tmp = String.valueOf(a);
StringBuilder sb = new StringBuilder(tmp);
sb.append("hello");
String d = sb.toString();

String
tmp = String.valueOf(a); StringBuilder sb = new StringBuilder(tmp); sb.append(b); String e = sb.toString();

補充:
類的final變數和普通變數有什麼區別?

public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = "hello";
        String d = "hello";
        String c = b + 2; 
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}

結果:

true
false

這裡面就是final變數和普通變數的區別了,當final變數是基本資料型別以及String型別時,如果在編譯期間能知道它的確切值,則編譯器會把它當做編譯期常量使用。也就是說在用到該final變數的地方,相當於直接訪問的這個常量,不需要在執行時確定。這種和C語言中的巨集替換有點像。因此在上面的一段程式碼中,由於變數b被final修飾,因此會被當做編譯器常量,所以在使用到b的地方會直接將變數b 替換為它的值。而對於變數d的訪問卻需要在執行時通過連結來進行。

下面反編譯一下看一下就知道確實編譯器做了手腳。

這裡寫圖片描述

不過要注意,只有在編譯期間能確切知道final變數值的情況下,編譯器才會進行這樣的優化,比如下面的這段程式碼就不會進行優化:

public class Test {
    public static void main(String[] args)  {
        String a = "hello2"; 
        final String b = getHello();
        String c = b + 2; 
        System.out.println((a == c));

    }

    public static String getHello() {
        return "hello";
    }
}

這段程式碼的輸出結果為false。

相關推薦

Java字串比較一道試題

題目: public class Test { public static void main(String[] args) { String a = "hello"; String b = "hello";

Java字串比較方法equals()和equalsIgnoreCase()的區別

1. equals() equals( )是比較兩個字串是否相等,它的一般表示式如下: /** * Compares this string to the specified object. The result is {@code * true} if and o

java 字串比較用=和equals區別

=:是比較兩個字串引用的地址是否相同,即是否指向同一個物件 equals方法:則比較字串的內容是否相同。 例如String a = "abc";     String b = "abc"; a == b返回true,a.equals(b)同樣返回true,這是為什

Java基礎一道試題

override ktr void ati star 打印 str @override ... 這個是我以前的一道面試題: public class MyThread extends Thread { @Override public void run() { tr

一道試題】一個".java"原始檔是否可以包括多個類(不是內部類)?有什麼限制?

這個面試題的答案在網上一搜一大把 但都是兩句話就結束了,我們來仔細看一下具體是什麼情況! 首先 肯定的一點是一個.java的原始檔中是可以包含多個類的,但是public類只能有一個,並且類名要和檔名相同,如果有兩個public類 就會報出以下的錯誤 這

一道試題來認識java類加載時機與過程【轉】

包含 布局 hello 印象 大致 周期 default () itl 說明:本文的內容是看了《深入理解Java虛擬機:JVM高級特性與最佳實踐》後為加印象和理解,便記錄了重要的內容。 1 開門見山 以前曾經看到過一個java的面試題,當時覺得此題很簡單,可是自己

關於Java類加載雙親委派機制的思考(附一道試題

另類 app 類庫 .com 任務 發現 clas context 表示 預定義類加載器和雙親委派機制 JVM預定義的三種類型類加載器: 啟動(Bootstrap)類加載器:是用本地代碼實現的類裝入器,它負責將 <Java_Runtime_Home>/l

Java繼承的幾道試題

有一個 str round .sh -s string ava 構造代碼塊 問題 第一題: 1 /* 2 看程序寫結果: 3 A:訪問成員變量的原則:就近原則。 4 B:this和super的問題: 5

有關java類、對象初始化的話題,從一道試題切入

() 深入理解java 補充 [] base sna 字體 都是 spa 最近在整理東西時,剛好碰到以前看的一道有關java類、對象初始化相關題目,覺得答案並不是非常好(記憶點比較差,不是很連貫)。加上剛好復習完類加載全過程的五個階段(加載-驗證-準備-解析-初始化),所以

java字串比較

在寫java時遇到比較一個物件的字串和一個字串是否相等的問題,遇到了一些坑。 在這段程式碼時,name1和name2的值都是"name",但是他們用==比較時確實不相等的。 首先,在java中String是一個物件,在用==比較兩個String物件的引用時,是比較

記Google的一道試題(java) Beautiful Numbers

Beautiful Numbers 思路: 13->三進位制->111 1 * 1+1 * 3+1 * 3 * 3=13 13%3=1,13/3=4 4%3=1,4/3=1 1%3=1,1/3=0 1.第一種情況:資料範圍比較小 程式碼: package

java基礎】多執行緒匿名內部類和lambda建立方式,及多執行緒的兩個試題

一、可以用匿名類和lambda兩個種方式建立多執行緒。 1.利用匿名內部類建立多執行緒並開啟。 new Thread() {//建立方式1 public void run() { for(int x=0; x<50; x++) { System.out

一道試題來認識java類載入時機與過程

說明:本文的內容是看了《深入理解Java虛擬機器:JVM高階特性與最佳實踐》後為加印象和理解,便記錄了重要的內容。 1  開門見山 以前曾經看到過一個java的面試題,當時覺得此題很簡單,可是自己把程式碼執行起來,可是結果並不是自己想象的那樣。題目如下: class SingleTon {

一道關於字串壓縮的試題

題目編寫一個演算法,實現基本的字串“壓縮”演算法,比如對於字串'abbbbffcccdddcc',經過演算法處理之後得到的輸出為'a1b4f2c3d3c2',如果處理後的字串長度不小於原串長度,則返回原串。演算法演算法一In [38]: def compress(s):

今天做到一道試題:Android程序的通訊方式

由於android系統中應用程式之間不能共享記憶體。因此,在不同應用程式之間互動資料(跨程序通訊)就稍微麻煩一些。在android SDK中提供了4種用於跨程序通訊的方式。這4種方式正好對應於android系統中4種應用程式元件:Activity、Content Provider、Broadcast和Se

一道試題比較兩個集合是否相等?

先宣告:本文內容是偏向於應用開發的,分析解答過程不適用於純演算法研發崗位。 朋友小P近來參加某網際網路公司的電話面試,被問到一道題:怎麼判斷兩個集合是否相等?注意,這是面試官的原話,一字不多,一字不少。 小P迅速回答道用雜湊,對方在電話裡也沒有要求給出具體的解決方案,就

java開發工程師職位面試遇到的一些試題

1.mysql 日期(天) group by 2.servlet生命週期3.各種方式定義的string的==和equals4.js string 定義新方法5.public private protected default區別6.多執行緒場景,及解決辦法7.談談你對資料庫事

一道試題比較synchronized和讀寫鎖

用第一種方法處理,整個過程比較粗線條,程式碼比較簡單單執行效率很低。這種方法的中心思想是不管你是什麼操作,但凡涉及到公共資源就都給你同步。這麼做可以是可以但是並不好。第二種用讀寫鎖處理顯然是對前者的一個優化,對第二種方法做如下幾點說明:關於unlock操作,我們知道只要是上了鎖就必須要解鎖,但是有這麼一種情

寫出float x 與“零值”比較的if語句——一道試題分析

寫出float  x 與“零值”比較的if語句 請寫出 float  x 與“零值”比較的 if 語句: const float EPSINON = 0.00001; if ((x >= - EPSINON) && (x <= EPSINON) 不

java比較試題(一)

  題目二    60. 執行以下程式,控制檯將列印:? public ExamTest { publicstatic void main(String[] args) { Syste