Java面試題及答案【第四部分】

Java知音發表於2018-05-07

1、一個".java"原始檔中是否可以包括多個類(不是內部類)?有什麼限制?

可以有多個類,但只能有一個public的類,並且public的類名必須與檔名相一致。


2、Java有沒有goto?

java中的保留字,現在沒有在java中使用。


3、說說&和&&的區別。

&和&&都可以用作邏輯與的運算子,表示邏輯與(and),當運算子兩邊的表示式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。

&&還具有短路的功能,即如果第一個表示式為false,則不再計算第二個表示式,例如,對於if(str!= null&& !str.equals(s))表示式,當str為null時,後面的表示式不會執行,所以不會出現NullPointerException如果將&&改為&,則會丟擲NullPointerException異常。If(x==33 &++y>0) y會增長,If(x==33 && ++y>0)不會增長

&還可以用作位運算子,當&操作符兩邊的表示式不是boolean型別時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來獲取該整數的最低4個bit位,例如,0x31 & 0x0f的結果為0x01。


4、在JAVA中如何跳出當前的多重巢狀迴圈?

在Java中,要想跳出多重迴圈,可以在外面的迴圈語句前定義一個標號,然後在裡層迴圈體的程式碼中使用帶有標號的break語句,即可跳出外層迴圈。

例如:

for(int i=0;i<10;i++){
for(intj=0;j<10;j++){
System.out.println(“i=” + i + “,j=” + j);
if(j == 5) break ok;
}
}
複製程式碼

        另外,我個人通常並不使用標號這種方式,而是讓外層的迴圈條件表示式的結果可以受到裡層迴圈體程式碼的控制,例如,要在二維陣列中查詢到某個數字。

int arr[][] ={{1,2,3},{4,5,6,7},{9}};boolean found = false;for(int i=0;i<arr.length&&!found;i++) {for(intj=0;j<arr[i].length;j++){System.out.println(“i=” + i + “,j=” + j);if(arr[i][j] ==5) {found =true;break;}}}複製程式碼


5、switch語句能否作用在byte上,能否作用在long上,能否作用在String上?

在switch(e)中,e只能是一個整數表示式或者列舉常量(更大字型),整數表示式可以是int基本型別或Integer包裝型別,由於byte,short,char都可以隱含轉換為int,所以,這些型別以及這些型別的包裝型別也是可以的。顯然,long和String型別都不符合switch的語法規定,並且不能被隱式轉換成int型別,所以,它們不能作用於swtich語句中。

switch語句能否作用在String上說錯了,Java1.7之後已經支援這種寫法了!


6、short s1= 1; s1 = (s1+1是int型別,而等號左邊的是short型別,所以需要強轉)1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?(沒有錯)

對於short s1= 1; s1 = s1 + 1;由於s1+1運算時會自動提升表示式的型別,所以結果是int型,再賦值給short型別s1時,編譯器將報告需要強制轉換型別的錯誤。

對於short s1= 1; s1 += 1;由於 +=是java語言規定的運算子,java編譯器會對它進行特殊處理,因此可以正確編譯。


7、char型變數中能不能存貯一箇中文漢字?為什麼?

char型變數是用來儲存Unicode編碼的字元的,unicode編碼字符集中包含了漢字,所以,char型變數中當然可以儲存漢字啦。不過,如果某個特殊的漢字沒有被包含在unicode編碼字符集中,那麼,這個char型變數中就不能儲存這個特殊漢字。補充說明:unicode編碼佔用兩個位元組,所以,char型別的變數也是佔用兩個位元組。


8、用最有效率的方法算出2乘以8等於幾?

2<< 3,(左移三位)因為將一個數左移n位,就相當於乘以了2的n次方,那麼,一個數乘以8只要將其左移3位即可,而位運算cpu直接支援的,效率最高,所以,2乘以8等於幾的最效率的方法是2<< 3。


9、使用final關鍵字修飾一個變數時,是引用不能變,還是引用的物件不能變?

使用final關鍵字修飾一個變數時,是指引用變數不能變,引用變數所指向的物件中的內容還是可以改變的。例如,對於如下語句:

final StringBuffer a=new StringBuffer("immutable");
複製程式碼


執行如下語句將報告編譯期錯誤:

a=new StringBuffer("");
複製程式碼


但是,執行如下語句則可以通過編譯:

a.append(" broken!");
複製程式碼

有人在定義方法的引數時,可能想採用如下形式來阻止方法內部修改傳進來的引數物件:

public void method(final StringBuffer param){}複製程式碼

實際上,這是辦不到的,在該方法內部仍然可以增加如下程式碼來修改引數物件:

param.append("a");
複製程式碼


10,靜態變數和例項變數的區別?

在語法定義上的區別:靜態變數前要加static關鍵字,而例項變數前則不加。

在程式執行時的區別:例項變數屬於某個物件的屬性,必須建立了例項物件,其中的例項變數才會被分配空間,才能使用這個例項變數。靜態變數不屬於某個例項物件,而是屬於類,所以也稱為類變數,只要程式載入了類的位元組碼,不用建立任何例項物件,靜態變數就會被分配空間,靜態變數就可以被使用了。總之,例項變數必須建立物件後才可以通過這個物件來使用,靜態變數則可以直接使用類名來引用。

例如,對於下面的程式,無論建立多少個例項物件,永遠都只分配了一個staticVar變數,並且每建立一個例項物件,這個staticVar就會加1;但是,每建立一個例項物件,就會分配一個instanceVar,即可能分配多個instanceVar,並且每個instanceVar的值都只自加了1次。

public class VariantTest{publicstatic int staticVar = 0;publicint instanceVar = 0;publicVariantTest(){staticVar++;instanceVar++;System.out.println(staticVar +instanceVar);}}複製程式碼


11、是否可以從一個static方法內部發出對非static方法的呼叫?

不可以。因為非static方法是要與物件關聯在一起的,必須建立一個物件後,才可以在該物件上進行方法呼叫,而static方法呼叫時不需要建立物件,可以直接呼叫。也就是說,當一個static方法被呼叫時,可能還沒有建立任何例項物件,如果從一個static方法中發出對非static方法的呼叫,那個非static方法是關聯到哪個物件上的呢?這個邏輯無法成立,所以,一個static方法內部發出對非static方法的呼叫。


12、Integer與int的區別

int是java提供的8種原始資料型別之一。Java為每個原始型別提供了封裝類,Integer是java為int提供的封裝類。int的預設值為0,而Integer的預設值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況。

例如:要想表達出沒有參加考試和考試成績為0的區別,則只能使用Integer。在JSP開發中,Integer的預設為null,所以用el表示式在文字框中顯示時,值為空白字串,而int預設的預設值為0,所以用el表示式在文字框中顯示時,結果為0,所以,int不適合作為web層的表單資料的型別。

在Hibernate中,如果將OID定義為Integer型別,那麼Hibernate就可以根據其值是否為null而判斷一個物件是否是臨時的,如果將OID定義為了int型別,還需要在hbm對映檔案中設定其unsaved-value屬性為0。

另外,Integer提供了多個與整數相關的操作方法,例如,將一個字串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。


13、Math.round(11.5)等於多少?Math.round(-11.5)等於多少?

Math類中提供了三個與取整有關的方法:ceil、floor、round,這些方法的作用與它們的英文名稱的含義相對應。

例如,ceil的英文意義是天花板,該方法就表示向上取整,Math.ceil(11.3)的結果為12,Math.ceil(-11.3)的結果是-11;floor的英文意義是地板,該方法就表示向下取整,Math.ceil(11.6)的結果為11,Math.ceil(-11.6)的結果是-12;最難掌握的是round方法,它表示“四捨五入”,演算法為Math.floor(x+0.5),即將原來的數字加上0.5後再向下取整,所以,Math.round(11.5)的結果為12,Math.round(-11.5)的結果為-11。

這裡有一些筆誤,floor的英文意義是地板,該方法就表示向下取整,Math.floor(11.6)的結果為11,Math.floor(-11.6)的結果是-12;


14、Overload和Override的區別?Overloaded的方法是否可以改變返回值的型別?

Overload是過載的意思,Override是覆蓋的意思,也就是重寫。

過載Overload表示同一個類中可以有多個名稱相同的方法,但這些方法的引數列表各不相同(即引數個數或型別不同)。

重寫Override表示子類中的方法可以與父類中的某個方法的名稱和引數完全相同,通過子類建立的例項物件呼叫這個方法時,將呼叫子類中的定義方法,這相當於把父類中定義的那個完全相同的方法給覆蓋了,這也是物件導向程式設計的多型性的一種表現。子類覆蓋父類的方法時,只能比父類丟擲更少的異常,或者是丟擲父類丟擲的異常的子異常,因為子類可以解決父類的一些問題,不能比父類有更多的問題。子類方法的訪問許可權只能比父類的更大,不能更小。如果父類的方法是private型別,那麼,子類則不存在覆蓋的限制,相當於子類中增加了一個全新的方法。

至於Overloaded的方法是否可以改變返回值的型別這個問題,要看你倒底想問什麼呢?這個題目很模糊。如果幾個Overloaded的方法的引數列表不一樣,它們的返回者型別當然也可以不一樣。但我估計你想問的問題是:如果兩個方法的引數列表完全一樣,是否可以讓它們的返回值不同來實現過載Overload。這是不行的,我們可以用反證法來說明這個問題,因為我們有時候呼叫一個方法時也可以不定義返回結果變數,即不要關心其返回結果,例如,我們呼叫map.remove(key)方法時,雖然remove方法有返回值,但是我們通常都不會定義接收返回結果的變數,這時候假設該類中有兩個名稱和引數列表完全相同的方法,僅僅是返回型別不同,java就無法確定程式設計者倒底是想呼叫哪個方法了,因為它無法通過返回結果型別來判斷。

override可以翻譯為覆蓋,從字面就可以知道,它是覆蓋了一個方法並且對其重寫,以求達到不同的作用。對我們來說最熟悉的覆蓋就是對介面方法的實現,在介面中一般只是對方法進行了宣告,而我們在實現時,就需要實現介面宣告的所有方法。除了這個典型的用法以外,我們在繼承中也可能會在子類覆蓋父類中的方法。在覆蓋要注意以下的幾點:

1、覆蓋的方法的標誌必須要和被覆蓋的方法的標誌完全匹配,才能達到覆蓋的效果;

2、覆蓋的方法的返回值必須和被覆蓋的方法的返回一致;

3、覆蓋的方法所丟擲的異常必須和被覆蓋方法的所丟擲的異常一致,或者是其子類;

4、被覆蓋的方法不能為private,否則在其子類中只是新定義了一個方法,並沒有對其進行覆蓋。

Overload對我們來說可能比較熟悉,可以翻譯為過載,它是指我們可以定義一些名稱相同的方法,通過定義不同的輸入引數來區分這些方法,然後再呼叫時,VM就會根據不同的引數樣式,來選擇合適的方法執行。在使用過載要注意以下的幾點:

1、在使用過載時只能通過不同的引數樣式。例如,不同的引數型別,不同的引數個數,不同的引數順序(當然,同一方法內的幾個引數型別必須不一樣,例如可以是fun(int,float),但是不能為fun(int,int));

2、不能通過訪問許可權、返回型別、丟擲的異常進行過載;

3、方法的異常型別和數目不會對過載造成影響;

4、對於繼承來說,如果某一方法在父類中是訪問許可權是priavte,那麼就不能在子類對其進行過載,如果定義的話,也只是定義了一個新方法,而不會達到過載的效果。


15、介面是否可繼承介面?抽象類是否可實現(implements)介面?抽象類是否可繼承具體類(concreteclass)?抽象類中是否可以有靜態的main方法?

介面可以繼承介面。抽象類可以實現(implements)介面,抽象類可以繼承具體類。抽象類中可以有靜態的main方法。

備註:只要明白了介面和抽象類的本質和作用,這些問題都很好回答,你想想,如果你是java語言的設計者,你是否會提供這樣的支援,如果不提供的話,有什麼理由嗎?如果你沒有道理不提供,那答案就是肯定的了。

只要記住抽象類與普通類的唯一區別就是不能建立例項物件和允許有abstract方法。


16、Java中實現多型的機制是什麼?

靠的是父類或介面定義的引用變數可以指向子類或具體實現類的例項物件,而程式呼叫的方法在執行期才動態繫結,就是引用變數所指向的具體例項物件的方法,也就是記憶體里正在執行的那個物件的方法,而不是引用變數的型別中定義的方法。


17、abstractclass和interface語法上有什麼區別?


1.抽象類可以有構造方法,介面中不能有構造方法。

2.抽象類中可以有普通成員變數,介面中沒有普通成員變數

3.抽象類中可以包含非抽象的普通方法,介面中的所有方法必須都是抽象的,不能有非抽象的普通方法。

4. 抽象類中的抽象方法的訪問型別可以是public,protected和(預設型別,雖然

eclipse下不報錯,但應該也不行),但介面中的抽象方法只能是public型別的,並且預設即為public abstract型別。

5. 抽象類中可以包含靜態方法,介面中不能包含靜態方法

6. 抽象類和介面中都可以包含靜態成員變數,抽象類中的靜態成員變數的訪問型別可以任意,但介面中定義的變數只能是publicstatic final型別,並且預設即為publicstatic final型別。

7. 一個類可以實現多個介面,但只能繼承一個抽象類。


18、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?

abstract的method不可以是static的,因為抽象的方法是要被子類實現的,而static與子類扯不上關係!

native方法表示該方法要用另外一種依賴平臺的程式語言實現的,不存在著被子類實現的問題,所以,它也不能是抽象的,不能與abstract混用。例如,FileOutputSteam類要硬體打交道,底層的實現用的是作業系統相關的api實現;例如,在windows用c語言實現的,所以,檢視jdk的原始碼,可以發現FileOutputStream的open方法的定義如下:

private native void open(Stringname) throwsFileNotFoundException;
複製程式碼

        如果我們要用java呼叫別人寫的c語言函式,我們是無法直接呼叫的,我們需要按照java的要求寫一個c語言的函式,又我們的這個c語言函式去呼叫別人的c語言函式。由於我們的c語言函式是按java的要求來寫的,我們這個c語言函式就可以與java對接上,java那邊的對接方式就是定義出與我們這個c函式相對應的方法,java中對應的方法不需要寫具體的程式碼,但需要在前面宣告native。

關於synchronized與abstract合用的問題,我覺得也不行,因為在我幾年的學習和開發中,從來沒見到過這種情況,並且我覺得synchronized應該是作用在一個具體的方法上才有意義。而且,方法上的synchronized同步所使用的同步鎖物件是this,而抽象方法上無法確定this是什麼。


19、內部類可以引用它的包含類的成員嗎?有沒有什麼限制?

完全可以。如果不是靜態內部類,那沒有什麼限制!

如果你把靜態巢狀類當作內部類的一種特例,那在這種情況下不可以訪問外部類的普通成員變數,而只能訪問外部類中的靜態成員,例如,下面的程式碼:

class Outer{static int x;static class Inner{voidtest(){syso(x);}}}複製程式碼


20、String s = "Hello";s = s + "world!";這兩行程式碼執行後,原始的String物件中的內容到底變了沒有?

沒有。因為String被設計成不可變(immutable)類,所以它的所有物件都是不可變物件。在這段程式碼中,s原先指向一個String物件,內容是 "Hello",然後我們對s進行了+操作,那麼s所指向的那個物件是否發生了改變呢?答案是沒有。這時,s不指向原來那個物件了,而指向了另一個 String物件,內容為"Hello world!",原來那個物件還存在於記憶體之中,只是s這個引用變數不再指向它了。

通過上面的說明,我們很容易匯出另一個結論,如果經常對字串進行各種各樣的修改,或者說,不可預見的修改,那麼使用String來代表字串的話會引起很大的記憶體開銷。因為String物件建立之後不能再改變,所以對於每一個不同的字串,都需要一個String物件來表示。這時,應該考慮使用StringBuffer類,它允許修改,而不是每個不同的字串都要生成一個新的物件。並且,這兩種類的物件轉換十分容易。
同時,我們還可以知道,如果要使用內容相同的字串,不必每次都new一個String。例如我們要在構造器中對一個名叫s的String引用變數進行初始化,把它設定為初始值,應當這樣做:

public class Demo {
private String s;
...
public Demo {
s = "Initial Value";
}
...
}
複製程式碼


而非

s = new String("Initial Value");
複製程式碼


後者每次都會呼叫構造器,生成新物件,效能低下且記憶體開銷大,並且沒有意義,因為String物件不可改變,所以對於內容相同的字串,只要一個String物件來表示就可以了。也就說,多次呼叫上面的構造器建立多個物件,他們的 String型別屬性s都指向同一個物件。
上面的結論還基於這樣一個事實:對於字串常量,如果內容相同,Java認為它們代表同一個String物件。而用關鍵字new呼叫構造器,總是會建立一個新的物件,無論內容是否相同。
至於為什麼要把String類設計成不可變類,是它的用途決定的。其實不只String,很多Java標準類庫中的類都是不可變的。在開發一個系統的時候,我們有時候也需要設計不可變類,來傳遞一組相關的值,這也是物件導向思想的體現。不可變類有一些優點,比如因為它的物件是隻讀的,所以多執行緒併發訪問也不會有任何問題。當然也有一些缺點,比如每個不同的狀態都要一個物件來代表,可能會造成效能上的問題。所以Java標準類庫還提供了一個可變版本,即StringBuffer。


21、ArrayList和Vector的區別

這兩個類都實現了List介面(List介面繼承了Collection介面),他們都是有序集合,即儲存在這兩個集合中的元素的位置都是有順序的,相當於一種動態的陣列,我們以後可以按位置索引號取出某個元素,並且其中的資料是允許重複的,這是與HashSet之類的集合的最大不同處,HashSet之類的集合不可以按索引號去檢索其中的元素,也不允許有重複的元素。

ArrayList與Vector的區別主要包括兩個方面:.
(1)同步性:

Vector是執行緒安全的,也就是說是它的方法之間是執行緒同步的,而ArrayList是執行緒序不安全的,它的方法之間是執行緒不同步的。如果只有一個執行緒會訪問到集合,那最好是使用ArrayList,因為它不考慮執行緒安全,效率會高些;如果有多個執行緒會訪問到集合,那最好是使用Vector,因為不需要我們自己再去考慮和編寫執行緒安全的程式碼。

(2)資料增長:

ArrayList與Vector都有一個初始的容量大小,當儲存進它們裡面的元素的個數超過了容量時,就需要增加ArrayList與Vector的儲存空間,每次要增加儲存空間時,不是隻增加一個儲存單元,而是增加多個儲存單元,每次增加的儲存單元的個數在記憶體空間利用與程式效率之間要取得一定的平衡。Vector預設增長為原來兩倍,而ArrayList的增長策略在文件中沒有明確規定(從原始碼看到的是增長為原來的1.5倍)。ArrayList與Vector都可以設定初始的空間大小,Vector還可以設定增長的空間大小,而ArrayList沒有提供設定增長空間的方法。

總結:即Vector增長原來的一倍,ArrayList增加原來的0.5倍。


22、HashMap和Hashtable的區別

HashMap是Hashtable的輕量級實現(非執行緒安全的實現),他們都完成了Map介面,主要區別在於HashMap允許空(null)鍵值(key),由於非執行緒安全,在只有一個執行緒訪問的情況下,效率要高於Hashtable。

HashMap允許將null作為一個entry的key或者value,而Hashtable不允許。

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因為contains方法容易讓人引起誤解。

Hashtable繼承自Dictionary類,而HashMap是Java1.2引進的Map interface的一個實現。

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多個執行緒訪問Hashtable時,不需要自己為它的方法實現同步,而HashMap就必須為之提供同步。

就HashMap與HashTable主要從三方面來說。
一.歷史原因:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map介面的一個實現
二.同步性:Hashtable是執行緒安全的,也就是說是同步的,而HashMap是執行緒序不安全的,不是同步的
三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value


23、List和 Map區別?

一個是儲存單列資料的集合,另一個是儲存鍵和值這樣的雙列資料的集合,List中儲存的資料是有順序,並且允許重複;Map中儲存的資料是沒有順序的,其鍵是不能重複的,它的值是可以有重複的。


24、List,Set, Map是否繼承自Collection介面?

List,Set是,Map不是


25、List、Map、Set三個介面,存取元素時,各有什麼特點?

(這樣的題比較考水平,兩個方面的水平:一是要真正明白這些內容,二是要有較強的總結和表述能力。)

首先,List與Set具有相似性,它們都是單列元素的集合,所以,它們有一個共同的父介面,叫Collection。Set裡面不允許有重複的元素,即不能有兩個相等(注意,不是僅僅是相同)的物件,即假設Set集合中有了一個A物件,現在我要向Set集合再存入一個B物件,但B物件與A物件equals相等,則B物件儲存不進去,所以,Set集合的add方法有一個boolean的返回值,當集合中沒有某個元素,此時add方法可成功加入該元素時,則返回true,當集合含有與某個元素equals相等的元素時,此時add方法無法加入該元素,返回結果為false。Set取元素時,不能細說要取第幾個,只能以Iterator介面取得所有的元素,再逐一遍歷各個元素。

List表示有先後順序的集合,注意,不是那種按年齡、按大小、按價格之類的排序。當我們多次呼叫add(Obje)方法時,每次加入的物件就像火車站買票有排隊順序一樣,按先來後到的順序排序。有時候,也可以插隊,即呼叫add(intindex,Obj e)方法,就可以指定當前物件在集合中的存放位置。一個物件可以被反覆儲存進List中,每呼叫一次add方法,這個物件就被插入進集合中一次,其實,並不是把這個物件本身儲存進了集合中,而是在集合中用一個索引變數指向這個物件,當這個物件被add多次時,即相當於集合中有多個索引指向了這個物件,如圖x所示。List除了可以用Iterator介面取得所有的元素,再逐一遍歷各個元素之外,還可以呼叫get(index i)來明確說明取第幾個。

Map與List和Set不同,它是雙列的集合,其中有put方法,定義如下:put(obj key,obj value),每次儲存時,要儲存一對key/value,不能儲存重複的key,這個重複的規則也是按equals比較相等。取則可以根據key獲得相應的value,即get(Object key)返回值為key所對應的value。另外,也可以獲得所有的key的結合,還可以獲得所有的value的結合,還可以獲得key和value組合成的Map.Entry物件的集合。

List以特定次序來持有元素,可有重複元素。Set無法擁有重複元素,內部排序。Map儲存key-value值,value可多值。


26、說出ArrayList,Vector,LinkedList的儲存效能和特性

ArrayList和Vector都是使用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及陣列元素移動等記憶體操作,所以索引資料快而插入資料慢,Vector由於使用了synchronized方法(執行緒安全),通常效能上較ArrayList差。而LinkedList使用雙向連結串列實現儲存,按序號索引資料需要進行前向或後向遍歷,索引就變慢了,但是插入資料時只需要記錄本項的前後項即可,所以插入速度較快。

LinkedList也是執行緒不安全的,LinkedList提供了一些方法,使得LinkedList可以被當作堆疊和佇列來使用。


27、去掉一個Vector集合中重複的元素

Vector newVector = new Vector();For (int i=0;i<vector.size();i++){Object obj = vector.get(i);if(!newVector.contains(obj);newVector.add(obj);}複製程式碼

還有一種簡單的方式,利用了Set不允許重複元素:

HashSetset = new HashSet(vector);


28、Collection和Collections的區別。

Collection是集合類的上級介面,繼承他的介面主要有Set和List.

Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜尋、排序、執行緒安全化等操作。


29、Set裡的元素是不能重複的,那麼用什麼方法來區分重複與否呢?是用==還是equals()?它們有何區別?

Set裡的元素是不能重複的,元素重複與否是使用equals()方法進行判斷的。

==和equal區別也是考爛了的題,這裡說一下:

==操作符專門用來比較兩個變數的值是否相等,也就是用於比較變數所對應的記憶體中所儲存的數值是否相同,要比較兩個基本型別的資料或兩個引用變數是否相等,只能用==操作符。

equals方法是用於比較兩個獨立物件的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個物件是獨立的。

比如:兩條new語句建立了兩個物件,然後用a/b這兩個變數分別指向了其中一個物件,這是兩個不同的物件,它們的首地址是不同的,即a和b中儲存的數值是不相同的,所以,表示式a==b將返回false,而這兩個物件中的內容是相同的,所以,表示式a.equals(b)將返回true。


30、你所知道的集合類都有哪些?主要方法?

最常用的集合類是 List 和 Map。 List的具體實現包括 ArrayList和 Vector,它們是可變大小的列表,比較適合構建、儲存和操作任何型別物件的元素列表。 List適用於按數值索引訪問元素的情形。

Map 提供了一個更通用的元素儲存方法。 Map集合類用於儲存元素對(稱作"鍵"和"值"),其中每個鍵對映到一個值。

它們都有增刪改查的方法。

對於set,大概的方法是add,remove, contains等

對於map,大概的方法就是put,remove,contains等

List類會有get(int index)這樣的方法,因為它可以按順序取元素,而set類中沒有get(int index)這樣的方法。List和set都可以迭代出所有元素,迭代時先要得到一個iterator物件,所以,set和list類都有一個iterator方法,用於返回那個iterator物件。map可以返回三個集合,一個是返回所有的key的集合,另外一個返回的是所有value的集合,再一個返回的key和value組合成的EntrySet物件的集合,map也有get方法,引數是key,返回值是key對應的value,這個自由發揮,也不是考記方法的能力,這些程式設計過程中會有提示,結合他們三者的不同說一下用法就行。


Java知音公眾號整理一些各大公司常用的面試筆試題,供大家在每天閒暇之餘學習其中幾道題目,日積月累,等到出去面試時,一切都水到渠成,面試時就自然會遊刃有餘了。

Java面試題及答案【第四部分】


相關文章