大數(shù)據(jù)面試題(三)
160.說(shuō)說(shuō)數(shù)據(jù)類型之間的轉(zhuǎn)換:
1 ) 如何將字符串轉(zhuǎn)換為基本數(shù)據(jù)類型?
2 ) 如何將基本數(shù)據(jù)類型轉(zhuǎn)換為字符串?
答:1 ) 調(diào)用基本數(shù)據(jù)類型對(duì)應(yīng)的包裝類中的方法parseXXX(String)或valueOf(String)即可返回相應(yīng)基本類型;
2 ) 一種方法是將基本數(shù)據(jù)類型與空字符串(””)連接(+)即可獲得其所對(duì)應(yīng)的字符串;另一種方法是調(diào)用String 類中的valueOf(…)方法返回相應(yīng)字符串?
161.如何實(shí)現(xiàn)字符串的反轉(zhuǎn)及替換?
答:方法很多,可以自己寫(xiě)實(shí)現(xiàn)也可以使用String或StringBuffer / StringBuilder中的方法。有一道很常見(jiàn)的面試題是用遞歸實(shí)現(xiàn)字符串反轉(zhuǎn),代碼如下所示:
162.怎樣將GB2312編碼的字符串轉(zhuǎn)換為ISO-8859-1編碼的字符串?
答:代碼如下所示:
String s1 = "你好";
String s2 = newString(s1.getBytes("GB2312"), "ISO-8859-1");?
163.Java中的日期和時(shí)間:
1 ) 如何取得年月日、小時(shí)分鐘秒?
2 ) 如何取得從1970年1月1日0時(shí)0分0秒到現(xiàn)在的毫秒數(shù)?
3 ) 如何取得某月的最后一天?
4 ) 如何格式化日期?
答:操作方法如下所示:
1 ) 創(chuàng)建java.util.Calendar 實(shí)例,調(diào)用其get()方法傳入不同的參數(shù)即可獲得參數(shù)所對(duì)應(yīng)的值
2 ) 以下方法均可獲得該毫秒數(shù):
Calendar.getInstance().getTimeInMillis();
time.getActualMaximum(Calendar.DAY_OF_MONTH);
4 ) 利用java.text.DataFormat 的子類(如SimpleDateFormat類)中的format(Date)方法可將日期格式化。
164.打印昨天的當(dāng)前時(shí)刻。

165.Java反射技術(shù)主要實(shí)現(xiàn)類有哪些,作用分別是什么?
在JDK中,主要由以下類來(lái)實(shí)現(xiàn)Java反射機(jī)制,這些類都位于java.lang.reflect包中
1)Class類:代表一個(gè)類
2)Field 類:代表類的成員變量(屬性)
3)Method類:代表類的成員方法
4)Constructor 類:代表類的構(gòu)造方法
5)Array類:提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問(wèn)數(shù)組的元素的靜態(tài)方法
166.Class類的作用?生成Class對(duì)象的方法有哪些?
Class類是Java 反射機(jī)制的起源和入口,用于獲取與類相關(guān)的各種信息,提供了獲取類信息的相關(guān)方法。Class類繼承自O(shè)bject類
Class類是所有類的共同的圖紙。每個(gè)類有自己的對(duì)象,好比圖紙和實(shí)物的關(guān)系;每個(gè)類也可看做是一個(gè)對(duì)象,有共同的圖紙Class,存放類的 結(jié)構(gòu)信息,能夠通過(guò)相應(yīng)方法取出相應(yīng)信息:類的名字、屬性、方法、構(gòu)造方法、父類和接口
示 例
對(duì)象名
.getClass()
String str="bdqn";
Class clazz = str.getClass();
對(duì)象名
.getSuperClass()
Student stu = new Student();
Class c1 = stu.getClass();
Class c2 = stu.getSuperClass();
Class.forName()
Class clazz = Class.forName("java.lang.Object");
Class.forName("oracle.jdbc.driver.OracleDriver");
類名.class
類名.class
Class c2 = Student.class;
Class c2 = int.class
包裝類.TYPE
包裝類.TYPE
Class c2 = Boolean.TYPE;
167.反射的使用場(chǎng)合和作用、及其優(yōu)缺點(diǎn)
1)使用場(chǎng)合
在編譯時(shí)根本無(wú)法知道該對(duì)象或類可能屬于哪些類,程序只依靠運(yùn)行時(shí)信息來(lái)發(fā)現(xiàn)該對(duì)象和類的真實(shí)信息。
2)主要作用
通過(guò)反射可以使程序代碼訪問(wèn)裝載到JVM 中的類的內(nèi)部信息,獲取已裝載類的屬性信息,獲取已裝載類的方法,獲取已裝載類的構(gòu)造方法信息
3)反射的優(yōu)點(diǎn)
反射提高了Java程序的靈活性和擴(kuò)展性,降低耦合性,提高自適應(yīng)能力。它允許程序創(chuàng)建和控制任何類的對(duì)象,無(wú)需提前硬編碼目標(biāo)類;反射是其它一些常用語(yǔ)言,如C、C++、Fortran 或者Pascal等都不具備的
4) Java反射技術(shù)應(yīng)用領(lǐng)域很廣,如軟件測(cè)試等;許多流行的開(kāi)源框架例如Struts、Hibernate、Spring在實(shí)現(xiàn)過(guò)程中都采用了該技術(shù)
5)反射的缺點(diǎn)
性能問(wèn)題:使用反射基本上是一種解釋操作,用于字段和方法接入時(shí)要遠(yuǎn)慢于直接代碼。因此Java反射機(jī)制主要應(yīng)用在對(duì)靈活性和擴(kuò)展性要求很高的系統(tǒng)框架上,普通程序不建議使用。
使用反射會(huì)模糊程序內(nèi)部邏輯:程序人員希望在源代碼中看到程序的邏輯,反射等繞過(guò)了源代碼的技術(shù),因而會(huì)帶來(lái)維護(hù)問(wèn)題。反射代碼比相應(yīng)的直接代碼更復(fù)雜。
168.面向?qū)ο笤O(shè)計(jì)原則有哪些
面向?qū)ο笤O(shè)計(jì)原則是面向?qū)ο笤O(shè)計(jì)的基石,面向?qū)ο笤O(shè)計(jì)質(zhì)量的依據(jù)和保障,設(shè)計(jì)模式是面向?qū)ο笤O(shè)計(jì)原則的經(jīng)典應(yīng)用
1)單一職責(zé)原則SRP
2)開(kāi)閉原則OCP
3)里氏替代原則LSP
4)依賴注入原則DIP
5)接口分離原則ISP
6)迪米特原則LOD
7)組合/聚合復(fù)用原則CARP
8)開(kāi)閉原則具有理想主義的色彩,它是面向?qū)ο笤O(shè)計(jì)的終極目標(biāo)。其他設(shè)計(jì)原則都可以看作是開(kāi)閉原則的實(shí)現(xiàn)手段或方法

String相關(guān):
169.下面程序的運(yùn)行結(jié)果是()(選擇一項(xiàng))

A.true
B.false
C.hello
D.he
答案:B
分析:str1沒(méi)有使用new關(guān)鍵字,在堆中沒(méi)有開(kāi)辟空間,其值”hello”在常量池中,str2使用new關(guān)鍵字創(chuàng)建了一個(gè)對(duì)象,在堆中開(kāi)辟了空間,”==”比較的是對(duì)象的引用,即內(nèi)存地址,所以str1與str2兩個(gè)對(duì)象的內(nèi)存地址是不相同的
170.Java語(yǔ)言中,String類中的indexOf()方法返回值的類型是()
A.int16
B.int32
C.int
D.long
答案:C
171.給定以下代碼,程序的運(yùn)行結(jié)果是 ()(選擇一項(xiàng))
A.goodandabcB.goodandgbcC.test okandabcD.test okandgbc
答案:B
分析:在方法調(diào)用時(shí),在change方法中對(duì)str的值進(jìn)行修改,是將str指向了常量江池中的”test ok”,而主方法中的ex.str仍然指向的是常量池中的”good”。字符型數(shù)組在方法調(diào)用時(shí),將主方法中ex.ch的引用傳遞給change方法中的ch,指向是堆中的同一堆空間,所以修改ch[0]的時(shí)候,ex.ch可以看到相同的修改后的結(jié)果。
172.執(zhí)行下列代碼后,哪個(gè)結(jié)論是正確的()(選擇兩項(xiàng))

A.s[10]為””
B.s[9]為null
C.s[0]為未定義
D.s.length為10
答案:BD
分析: 引用數(shù)據(jù)類型的默認(rèn)值均為null
s.length數(shù)組的長(zhǎng)度
173.實(shí)現(xiàn)String類的replaceAll方法
思路說(shuō)明:replaceAll方法的本質(zhì)是使用正則表達(dá)式進(jìn)行匹配,最終調(diào)用的其實(shí)是Matcher對(duì)象的replaceAll方法。

174.在“=”后填寫(xiě)適當(dāng)?shù)膬?nèi)容:
String []a=new String[10];
則:a[0]~a[9]=null;
a.length=10;
如果是int[]a=new int[10];
則:a[0]~a[9]= (0)
a.length= (10)
175.是否可以繼承String類?
答:不可以,因?yàn)镾tring類有final修飾符,而final修飾的類是不能被繼承的,實(shí)現(xiàn)細(xì)節(jié)不允許改變。
public final class String implements java.io.Serializable,
Comparable< String>, CharSequence
176.給定兩個(gè)字符串s和t, 寫(xiě)一個(gè)函數(shù)來(lái)決定是否t是s的重組詞。你可以假設(shè)字符串只包含小寫(xiě)字母。

177.String s=new String(“abc”);創(chuàng)建了幾個(gè)String對(duì)象。
兩個(gè)或一個(gè),”abc”對(duì)應(yīng)一個(gè)對(duì)象,這個(gè)對(duì)象放在字符串常量緩沖區(qū),常量”abc”不管出現(xiàn)多少遍,都是緩沖區(qū)中的那一個(gè)。New String每寫(xiě)一遍,就創(chuàng)建一個(gè)新的對(duì)象,它一句那個(gè)常量”abc”對(duì)象的內(nèi)容來(lái)創(chuàng)建出一個(gè)新String對(duì)象。如果以前就用過(guò)’abc’,這句代表就不會(huì)創(chuàng)建”abc”自己了,直接從緩沖區(qū)拿。
178.輸出結(jié)果?

179.下列程序的輸出結(jié)果是什么?

0 Hello world
1 Hello world
2 Hello world
3 Hello world
4 Hello world
5 Hello world
6 Hello world
7 Hello world
8 Hello world
9 Hello world
180.關(guān)于java.lang.String類,以下描述正確的一項(xiàng)是()
A.String類是final類故不可繼承
B.String類final類故可以繼承
C.String類不是final類故不可繼承
D.String;類不是final類故可以繼承
答案:A
181.下面哪個(gè)是正確的()
A.String temp[ ] = new String{“a”,”b”,”c”};
B.String temp[ ] = {“a”,”b”,”c”};
C.String temp= {“a”,”b”,”c”};
D.String[ ] temp = {“a”,”b”,”c”};
答案:BD
182.已知如下代碼:執(zhí)行結(jié)果是什么()

A.false true true
B.true false true
C.true true false
D.true true false
答案:A
183.字符串如何轉(zhuǎn)換為int類型

184.寫(xiě)一個(gè)方法,實(shí)現(xiàn)字符串的反轉(zhuǎn),如:輸入abc,輸出cba

185.編寫(xiě)java,將“I follow Bill Gate.Tom Gate.John Gate”中的“Gate”全部替換為“Gates”

186.String 是最基本的數(shù)據(jù)類型嗎?
答: 不是 。Java中的基本數(shù)據(jù)類型只有8個(gè):byte、short、int、long、float、double、char、boolean;除了基本類型(primitive type)和枚舉類型(enumeration type),剩下的都是引用類型(reference type)。
187.String 和StringBuilder、StringBuffer 的區(qū)別?
答: Java 平臺(tái)提供了兩種類型的字符串:String和StringBuffer / StringBuilder
相同點(diǎn):
它們都可以儲(chǔ)存和操作字符串,同時(shí)三者都使用final修飾,都屬于終結(jié)類不能派生子類,操作的相關(guān)方法也類似例如獲取字符串長(zhǎng)度等;
不同點(diǎn):
其中String是只讀字符串,也就意味著String引用的字符串內(nèi)容是不能被改變的,而StringBuffer和StringBuilder類表示的字符串對(duì)象可以直接進(jìn)行修改,在修改的同時(shí)地址值不會(huì)發(fā)生改變。StringBuilder是JDK 1.5中引入的,它和StringBuffer的方法完全相同,區(qū)別在于它是在單線程環(huán)境下使用的,因?yàn)樗乃蟹矫娑紱](méi)有被synchronized修飾,因此它的效率也比StringBuffer略高。在此重點(diǎn)說(shuō)明一下,String、StringBuffer、StringBuilder三者類型不一樣,無(wú)法使用equals()方法比較其字符串內(nèi)容是否一樣!
補(bǔ)充1:有一個(gè)面試題問(wèn):有沒(méi)有哪種情況用+做字符串連接比調(diào)用StringBuffer / StringBuilder對(duì)象的append方法性能更好?如果連接后得到的字符串在靜態(tài)存儲(chǔ)區(qū)中是早已存在的,那么用+做字符串連接是優(yōu)于StringBuffer / StringBuilder的append方法的。

解析:
String類存在intern()方法,含義如下:返回字符串對(duì)象的規(guī)范化表示形式。它遵循以下規(guī)則:對(duì)于任意兩個(gè)字符串 s 和 t,當(dāng)且僅當(dāng) s.equals(t) 為 true 時(shí),s.intern()?==?t.intern() 才為 true。
字符串比較分為兩種形式,一種使用比較運(yùn)算符”==”比較,他們比較的是各自的字符串在內(nèi)存當(dāng)中的地址值是否相同;一種是使用equals()方法進(jìn)行比較,比較的是兩個(gè)字符串的內(nèi)容是否相同!

結(jié)果如下:
a == b-->false
a == c-->true
a.equals(b)-->true
a.equals(c)-->true
a.intern() == b.intern()-->true
188.String類為什么是final的
答:1) 為了效率。若允許被繼承,則其高度的被使用率可能會(huì)降低程序的性能。
2)為了安全。JDK中提供的好多核心類比如String,這類的類的內(nèi)部好多方法的實(shí)現(xiàn)都不是java編程語(yǔ)言本身編寫(xiě)的,好多方法都是調(diào)用的操作系統(tǒng)本地的API,這就是著名的“本地方法調(diào)用”,也只有這樣才能做事,這種類是非常底層的,和操作系統(tǒng)交流頻繁的,那么如果這種類可以被繼承的話,如果我們?cè)侔阉姆椒ㄖ貙?xiě)了,往操作系統(tǒng)內(nèi)部寫(xiě)入一段具有惡意攻擊性質(zhì)的代碼什么的,這不就成了核心病毒了么?不希望別人改,這個(gè)類就像一個(gè)工具一樣,類的提供者給我們提供了, 就希望我們直接用就完了,不想讓我們隨便能改,其實(shí)說(shuō)白了還是安全性,如果隨便能改了,那么java編寫(xiě)的程序肯定就很不穩(wěn)定,你可以保證自己不亂改, 但是將來(lái)一個(gè)項(xiàng)目好多人來(lái)做,管不了別人,再說(shuō)有時(shí)候萬(wàn)一疏忽了呢?他也不是估計(jì)的, 所以這個(gè)安全性是很重要的,java和C++相比,優(yōu)點(diǎn)之一就包括這一點(diǎn)。
189.String類型是基本數(shù)據(jù)類型嗎?基本數(shù)據(jù)類型有哪些
1) 基本數(shù)據(jù)類型包括byte、short/char、int、long、float、double、boolean
2 ) java.lang.String類是引用數(shù)據(jù)類型,并且是final類型的,因此不可以繼承這個(gè)類、不能修改這個(gè)類。為了提高效率節(jié)省空間,我們應(yīng)該用StringBuffer類
190.String?s="Hello";s=s+"world!";執(zhí)行后,是否是對(duì)前面s指向空間內(nèi)容的修改?
答:不是對(duì)前面s指向空間內(nèi)容的直接修改。
因?yàn)镾tring被設(shè)計(jì)成不可變(immutable)類,所以它的所有對(duì)象都是不可變對(duì)象。在這段代碼中,s原先指向一個(gè)String對(duì)象,內(nèi)容是 "Hello",然后我們對(duì)s進(jìn)行了+操作,那么s所指向的那個(gè)對(duì)象是否發(fā)生了改變呢?答案是沒(méi)有。這時(shí),s不指向原來(lái)那個(gè)對(duì)象了,而指向了另一個(gè) String對(duì)象,內(nèi)容為"Hello?world!",原來(lái)那個(gè)對(duì)象還存在于內(nèi)存之中,只是s這個(gè)引用變量不再指向它了。
通過(guò)上面的說(shuō)明,我們很容易導(dǎo)出另一個(gè)結(jié)論,如果經(jīng)常對(duì)字符串進(jìn)行各種各樣的修改,或者說(shuō),不可預(yù)見(jiàn)的修改,那么使用String來(lái)代表字符串的話會(huì)引起很大的內(nèi)存開(kāi)銷。因?yàn)?String對(duì)象建立之后不能再改變,所以對(duì)于每一個(gè)不同的字符串,都需要一個(gè)String對(duì)象來(lái)表示。這時(shí),應(yīng)該考慮使用StringBuffer類,它允許修改,而不是每個(gè)不同的字符串都要生成一個(gè)新的對(duì)象。并且,這兩種類的對(duì)象轉(zhuǎn)換十分容易。
同時(shí),我們還可以知道,如果要使用內(nèi)容相同的字符串,不必每次都new一個(gè)String。例如我們要在構(gòu)造器中對(duì)一個(gè)名叫s的String引用變量進(jìn)行初始化,把它設(shè)置為初始值,應(yīng)當(dāng)這樣做:
而非

s?=?new?String("Initial?Value");
后者每次都會(huì)調(diào)用構(gòu)造器,生成新對(duì)象,性能低下且內(nèi)存開(kāi)銷大,并且沒(méi)有意義,因?yàn)镾tring對(duì)象不可改變,所以對(duì)于內(nèi)容相同的字符串,只要一個(gè)String對(duì)象來(lái)表示就可以了。也就說(shuō),多次調(diào)用上面的構(gòu)造器創(chuàng)建多個(gè)對(duì)象,他們的String類型屬性s都指向同一個(gè)對(duì)象。
上面的結(jié)論還基于這樣一個(gè)事實(shí):對(duì)于字符串常量,如果內(nèi)容相同,Java認(rèn)為它們代表同一個(gè)String對(duì)象。而用關(guān)鍵字new調(diào)用構(gòu)造器,總是會(huì)創(chuàng)建一個(gè)新的對(duì)象,無(wú)論內(nèi)容是否相同。
至于為什么要把String類設(shè)計(jì)成不可變類,是它的用途決定的。其實(shí)不只String,很多Java標(biāo)準(zhǔn)類庫(kù)中的類都是不可變的。在開(kāi)發(fā)一個(gè)系統(tǒng)的時(shí)候,我們有時(shí)候也需要設(shè)計(jì)不可變類,來(lái)傳遞一組相關(guān)的值,這也是面向?qū)ο笏枷氲捏w現(xiàn)。不可變類有一些優(yōu)點(diǎn),比如因?yàn)樗膶?duì)象是只讀的,所以多線程并發(fā)訪問(wèn)也不會(huì)有任何問(wèn)題。當(dāng)然也有一些缺點(diǎn),比如每個(gè)不同的狀態(tài)都要一個(gè)對(duì)象來(lái)代表,可能會(huì)造成性能上的問(wèn)題。所以Java標(biāo)準(zhǔn)類庫(kù)還提供了一個(gè)可變版本,即 StringBuffer。
191.String s = new String("xyz");創(chuàng)建幾個(gè)String Object?
答:兩個(gè)或一個(gè),”xyz”對(duì)應(yīng)一個(gè)對(duì)象,這個(gè)對(duì)象放在字符串常量緩沖區(qū),常量”xyz”不管出現(xiàn)多少遍,都是緩沖區(qū)中的那一個(gè)。New String每寫(xiě)一遍,就創(chuàng)建一個(gè)新的對(duì)象,它一句那個(gè)常量”xyz”對(duì)象的內(nèi)容來(lái)創(chuàng)建出一個(gè)新String對(duì)象。如果以前就用過(guò)’xyz’,這句代表就不會(huì)創(chuàng)建”xyz”自己了,直接從緩沖區(qū)拿。
192.下面這條語(yǔ)句一共創(chuàng)建了多少個(gè)對(duì)象:String s="a"+"b"+"c"+"d";
答:對(duì)于如下代碼:
String s1 = "a";
String s2 = s1 + "b";
String s3 = "a" + "b";
System.out.println(s2 == "ab");
System.out.println(s3 == "ab");
第一條語(yǔ)句打印的結(jié)果為false,第二條語(yǔ)句打印的結(jié)果為true,這說(shuō)明javac編譯可以對(duì)字符串常量直接相加的表達(dá)式進(jìn)行優(yōu)化,不必要等到運(yùn)行期去進(jìn)行加法運(yùn)算處理,而是在編譯時(shí)去掉其中的加號(hào),直接將其編譯成一個(gè)這些常量相連的結(jié)果。
題目中的第一行代碼被編譯器在編譯時(shí)優(yōu)化后,相當(dāng)于直接定義一個(gè)”abcd”的字符串,所以,上面的代碼應(yīng)該只創(chuàng)建了一個(gè)String對(duì)象。
寫(xiě)如下兩行代碼,
String s = "a" + "b" + "c" + "d";
System.out.println(s == "abcd");
最終打印的結(jié)果應(yīng)該為true。
193.Java集合體系結(jié)構(gòu)(List、Set、Collection、Map的區(qū)別和聯(lián)系)

?

1、Collection 接口存儲(chǔ)一組不唯一,無(wú)序的對(duì)象
2、List 接口存儲(chǔ)一組不唯一,有序(插入順序)的對(duì)象
3、Set 接口存儲(chǔ)一組唯一,無(wú)序的對(duì)象
4、Map接口存儲(chǔ)一組鍵值對(duì)象,提供key到value的映射。Key無(wú)序,唯一。value不要求有序,允許重復(fù)。(如果只使用key存儲(chǔ),而不使用value,那就是Set)
194.Vector和ArrayList的區(qū)別和聯(lián)系
相同點(diǎn):
1)實(shí)現(xiàn)原理相同---底層都使用數(shù)組
2)功能相同---實(shí)現(xiàn)增刪改查等操作的方法相似
3)都是長(zhǎng)度可變的數(shù)組結(jié)構(gòu),很多情況下可以互用
不同點(diǎn):
1)Vector是早期JDK版本提供,ArrayList是新版本替代Vector的
2)Vector線程安全,ArrayList重速度輕安全,線程非安全長(zhǎng)度需增長(zhǎng)時(shí),Vector默認(rèn)增長(zhǎng)一倍,ArrayList增長(zhǎng)50%
195.ArrayList和LinkedList的區(qū)別和聯(lián)系
相同點(diǎn):
兩者都實(shí)現(xiàn)了List接口,都具有List中元素有序、不唯一的特點(diǎn)。
不同點(diǎn):
ArrayList實(shí)現(xiàn)了長(zhǎng)度可變的數(shù)組,在內(nèi)存中分配連續(xù)空間。遍歷元素和隨機(jī)訪問(wèn)元素的效率比較高;

LinkedList采用鏈表存儲(chǔ)方式。插入、刪除元素時(shí)效率比較高

196.HashMap和Hashtable的區(qū)別和聯(lián)系
相同點(diǎn):
實(shí)現(xiàn)原理相同,功能相同,底層都是哈希表結(jié)構(gòu),查詢速度快,在很多情況下可以互用
不同點(diǎn):
1、Hashtable是早期提供的接口,HashMap是新版JDK提供的接口
2、Hashtable繼承Dictionary類,HashMap實(shí)現(xiàn)Map接口
3、Hashtable線程安全,HashMap線程非安全
4、Hashtable不允許null值,HashMap允許null值
197.HashSet的使用和原理(hashCode()和equals())
1)哈希表的查詢速度特別快,時(shí)間復(fù)雜度為O(1)。
2)HashMap、Hashtable、HashSet這些集合采用的是哈希表結(jié)構(gòu),需要用到hashCode哈希碼,hashCode是一個(gè)整數(shù)值。
3)系統(tǒng)類已經(jīng)覆蓋了hashCode方法 自定義類如果要放入hash類集合,必須重寫(xiě)hashcode。如果不重寫(xiě),調(diào)用的是Object的hashcode,而Object的hashCode實(shí)際上是地址。
4)向哈希表中添加數(shù)據(jù)的原理:當(dāng)向集合Set中增加對(duì)象時(shí),首先集合計(jì)算要增加對(duì)象的hashCode碼,根據(jù)該值來(lái)得到一個(gè)位置用來(lái)存放當(dāng)前對(duì)象,如在該位置沒(méi)有一個(gè)對(duì)象存在的話,那么集合Set認(rèn)為該對(duì)象在集合中不存在,直接增加進(jìn)去。如果在該位置有一個(gè)對(duì)象存在的話,接著將準(zhǔn)備增加到集合中的對(duì)象與該位置上的對(duì)象進(jìn)行equals方法比較,如果該equals方法返回false,那么集合認(rèn)為集合中不存在該對(duì)象,在進(jìn)行一次散列,將該對(duì)象放到散列后計(jì)算出的新地址里。如果equals方法返回true,那么集合認(rèn)為集合中已經(jīng)存在該對(duì)象了,不會(huì)再將該對(duì)象增加到集合中了。
5)在哈希表中判斷兩個(gè)元素是否重復(fù)要使用到hashCode()和equals()。hashCode決定數(shù)據(jù)在表中的存儲(chǔ)位置,而equals判斷是否存在相同數(shù)據(jù)。
6) Y=K(X) :K是函數(shù),X是哈希碼,Y是地址
198.TreeSet的原理和使用(Comparable和comparator)
1)TreeSet集合,元素不允許重復(fù)且有序(自然順序)
2)TreeSet采用樹(shù)結(jié)構(gòu)存儲(chǔ)數(shù)據(jù),存入元素時(shí)需要和樹(shù)中元素進(jìn)行對(duì)比,需要指定比較策略。
3)可以通過(guò)Comparable(外部比較器)和Comparator(內(nèi)部比較器)來(lái)指定比較策略,實(shí)現(xiàn)了Comparable的系統(tǒng)類可以順利存入TreeSet。自定義類可以實(shí)現(xiàn)Comparable接口來(lái)指定比較策略。
4)可創(chuàng)建Comparator接口實(shí)現(xiàn)類來(lái)指定比較策略,并通過(guò)TreeSet構(gòu)造方法參數(shù)傳入。這種方式尤其對(duì)系統(tǒng)類非常適用。
199.集合和數(shù)組的比較(為什么引入集合)
數(shù)組不是面向?qū)ο蟮模嬖诿黠@的缺陷,集合完全彌補(bǔ)了數(shù)組的一些缺點(diǎn),比數(shù)組更靈活更實(shí)用,可大大提高軟件的開(kāi)發(fā)效率而且不同的集合框架類可適用于不同場(chǎng)合。具體如下:
1)數(shù)組的效率高于集合類.
2)數(shù)組能存放基本數(shù)據(jù)類型和對(duì)象,而集合類中只能放對(duì)象。
3)數(shù)組容量固定且無(wú)法動(dòng)態(tài)改變,集合類容量動(dòng)態(tài)改變。
4)數(shù)組無(wú)法判斷其中實(shí)際存有多少元素,length只告訴了array的容量。
5)集合有多種實(shí)現(xiàn)方式和不同的適用場(chǎng)合,而不像數(shù)組僅采用順序表方式。
6)集合以類的形式存在,具有封裝、繼承、多態(tài)等類的特性,通過(guò)簡(jiǎn)單的方法和屬性調(diào)用即可實(shí)現(xiàn)各種復(fù)雜操作,大大提高軟件的開(kāi)發(fā)效率。
200.Collection和Collections的區(qū)別
1)Collection是Java提供的集合接口,存儲(chǔ)一組不唯一,無(wú)序的對(duì)象。它有兩個(gè)子接口List和Set。
2)Java中還有一個(gè)Collections類,專門(mén)用來(lái)操作集合類 ,它提供一系列靜態(tài)方法實(shí)現(xiàn)對(duì)各種集合的搜索、排序、線程安全化等操作。
201.下列說(shuō)法正確的有()(選擇一項(xiàng))
A.LinkedList繼承自List
B.AbstractSet繼承自Set
C.HashSet繼承自AbstractSet
D.TreeMap繼承自HashMap
答案: C
分析:A:LinkedList實(shí)現(xiàn)List接口
B:AbstractSet實(shí)現(xiàn)Set接口
D:TreeMap繼承AbstractMap
202.Java的HashMap和Hashtable有什么區(qū)別HashSet和HashMap有什么區(qū)別?使用這些結(jié)構(gòu)保存的數(shù)需要重載的方法是哪些?
答:HashMap與Hashtable實(shí)現(xiàn)原理相同,功能相同,底層都是哈希表結(jié)構(gòu),查詢速度快,在很多情況下可以互用
兩者的主要區(qū)別如下
1、Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
2、Hashtable繼承Dictionary類,HashMap實(shí)現(xiàn)Map接口
3、Hashtable線程安全,HashMap線程非安全
4、Hashtable不允許null值,HashMap允許null值
HashSet與HashMap的區(qū)別
1、HashSet底層是采用HashMap實(shí)現(xiàn)的。HashSet 的實(shí)現(xiàn)比較簡(jiǎn)單,HashSet 的絕大部分方法都是通過(guò)調(diào)用 HashMap 的方法來(lái)實(shí)現(xiàn)的,因此 HashSet 和 HashMap 兩個(gè)集合在實(shí)現(xiàn)本質(zhì)上是相同的。
2、HashMap的key就是放進(jìn)HashSet中對(duì)象,value是Object類型的。
3、當(dāng)調(diào)用HashSet的add方法時(shí),實(shí)際上是向HashMap中增加了一行(key-value對(duì)),該行的key就是向HashSet增加的那個(gè)對(duì)象,該行的value就是一個(gè)Object類型的常量
203.列出Java中的集合類層次結(jié)構(gòu)?
答:Java中集合主要分為兩種:Collection和Map。Collection是List和Set接口的父接口;ArrayList和LinkedList是List的實(shí)現(xiàn)類;HashSet和TreeSet是Set的實(shí)現(xiàn)類;LinkedHashSet是HashSet的子類。HashMap和TreeMap是Map的實(shí)現(xiàn)類;LinkedHashMap是HashMap的子類。
圖中:虛線框中為接口,實(shí)線框中為類。

204.List,Set,Map各有什么特點(diǎn)
答:List 接口存儲(chǔ)一組不唯一,有序(插入順序)的對(duì)象。
Set 接口存儲(chǔ)一組唯一,無(wú)序的對(duì)象。
Map接口存儲(chǔ)一組鍵值對(duì)象,提供key到value的映射。key無(wú)序,唯一。value不要求有序,允許重復(fù)。(如果只使用key存儲(chǔ),而不使用value,那就是Set)。
205.ArrayList list=new ArrayList(20);中的list擴(kuò)充幾次()
A.0
B.1
C.2
D.3
答案:A
分析:已經(jīng)指定了長(zhǎng)度, 所以不擴(kuò)容
206.List、Set、Map哪個(gè)繼承自Collection接口,一下說(shuō)法正確的是()
A.List Map
B.Set Map
C.List Set
D.List Map Set
答案:C
分析:Map接口繼承了java.lang.Object類,但沒(méi)有實(shí)現(xiàn)任何接口.
207.合并兩個(gè)有序的鏈表

208.用遞歸方式實(shí)現(xiàn)鏈表的轉(zhuǎn)置。

209.給定一個(gè)不包含相同元素的整數(shù)集合,nums,返回所有可能的子集集合。解答中集合不能包含重復(fù)的子集。

210.以下結(jié)構(gòu)中,哪個(gè)具有同步功能()
A.HashMap
B.ConcurrentHashMap
C.WeakHashMap
D.TreeMap
答案:B
分析:
A,C,D都線程不安全,B線程安全,具有同步功能
211.以下結(jié)構(gòu)中,插入性能最高的是()
A.ArrayList
B.Linkedlist
C.tor
D.Collection
答案:B
分析:
數(shù)組插入、刪除效率差,排除A
tor不是java里面的數(shù)據(jù)結(jié)構(gòu),是一種網(wǎng)絡(luò)路由技術(shù);因此排除C
Collection 是集合的接口,不是某種數(shù)據(jù)結(jié)構(gòu);因此排除D
212.以下結(jié)構(gòu)中,哪個(gè)最適合當(dāng)作stack使用()
A.LinkedHashMap
B.LinkedHashSet
C.LinkedList
答案:C
分析:
Stack是先進(jìn)后出的線性結(jié)構(gòu);所以鏈表比較合適;不需要散列表的數(shù)據(jù)結(jié)構(gòu)
213.Map的實(shí)現(xiàn)類中,哪些是有序的,哪些是無(wú)序的,有序的是如何保證其有序性,你覺(jué)得哪個(gè)有序性性能更高,你有沒(méi)有更好或者更高效的實(shí)現(xiàn)方式?
答:1. Map的實(shí)現(xiàn)類有HashMap,LinkedHashMap,TreeMap
2. HashMap是有無(wú)序的,LinkedHashMap和TreeMap都是有序的(LinkedHashMap記錄了添加數(shù)據(jù)的順序;TreeMap默認(rèn)是自然升序)
3. LinkedHashMap底層存儲(chǔ)結(jié)構(gòu)是哈希表+鏈表,鏈表記錄了添加數(shù)據(jù)的順序
4. TreeMap底層存儲(chǔ)結(jié)構(gòu)是二叉樹(shù),二叉樹(shù)的中序遍歷保證了數(shù)據(jù)的有序性
5. LinkedHashMap有序性能比較高,因?yàn)榈讓訑?shù)據(jù)存儲(chǔ)結(jié)構(gòu)采用的哈希表
214.下面的代碼在絕大部分時(shí)間內(nèi)都運(yùn)行得很正常,請(qǐng)問(wèn)什么情況下會(huì)出現(xiàn)問(wèn)題?根源在哪里?

答:將if( list.size() <= 0 )改成:while( list.size() <= 0 )
215.TreeMap和TreeSet在排序時(shí)如何比較元素?Collections工具類中的sort()方法如何比較元素?
答:TreeSet要求存放的對(duì)象所屬的類必須實(shí)現(xiàn)Comparable接口,該接口提供了比較元素的compareTo()方法,當(dāng)插入元素時(shí)會(huì) 回調(diào)該方法比較元素的大小。TreeMap要求存放的鍵值對(duì)映射的鍵必須實(shí)現(xiàn)Comparable接口從而根據(jù)鍵對(duì)元素進(jìn)行排序。Collections 工具類的sort方法有兩種重載的形式,第一種要求傳入的待排序容器中存放的對(duì)象比較實(shí)現(xiàn)Comparable接口以實(shí)現(xiàn)元素的比較;第二種不強(qiáng)制性的要求容器中的元素必須可比較,但是要求傳入第二個(gè)參數(shù),參數(shù)是Comparator接口的子類型(需要重寫(xiě)compare方法實(shí)現(xiàn)元素的比較),相當(dāng)于一個(gè)臨時(shí)定義的排序規(guī)則,其實(shí)就是是通過(guò)接口注入比較元素大小的算法,也是對(duì)回調(diào)模式的應(yīng)用。
216.List里面如何剔除相同的對(duì)象?請(qǐng)簡(jiǎn)單用代碼實(shí)現(xiàn)一種方法

217.Java.util.Map的實(shí)現(xiàn)類有
分析:Java中的java.util.Map的實(shí)現(xiàn)類
1、HashMap
2、Hashtable
3、LinkedHashMap
4、TreeMap
218.下列敘述中正確的是()
A.循環(huán)隊(duì)列有隊(duì)頭和隊(duì)尾兩個(gè)指針,因此,循環(huán)隊(duì)列是非線性結(jié)構(gòu)
B.在循環(huán)隊(duì)列中,只需要隊(duì)頭指針就能反映隊(duì)列中元素的動(dòng)態(tài)變化情況
C.在循環(huán)隊(duì)列中,只需要隊(duì)尾指針就能反映隊(duì)列中元素的動(dòng)態(tài)變化情況
D.在循環(huán)隊(duì)列中元素的個(gè)數(shù)是由隊(duì)頭指針和隊(duì)尾指針共同決定的
答案:D
分析:循環(huán)隊(duì)列中元素的個(gè)數(shù)是由隊(duì)首指針和隊(duì)尾指針共同決定的,元素的動(dòng)態(tài)變化也是通過(guò)隊(duì)首指針和隊(duì)尾指針來(lái)反映的,當(dāng)隊(duì)首等于隊(duì)尾時(shí),隊(duì)列為空。
219.List、Set、Map 是否繼承自Collection 接口?
答:List、Set 的父接口是Collection,Map 不是其子接口,而是與Collection接口是平行關(guān)系,互不包含。

Map是鍵值對(duì)映射容器,與List和Set有明顯的區(qū)別,而Set存儲(chǔ)的零散的元素且不允許有重復(fù)元素(數(shù)學(xué)中的集合也是如此),List是線性結(jié)構(gòu)的容器,適用于按數(shù)值索引訪問(wèn)元素的情形。?
220.說(shuō)出ArrayList、Vector、LinkedList 的存儲(chǔ)性能和特性?
答:ArrayList 和Vector都是使用數(shù)組方式存儲(chǔ)數(shù)據(jù),此數(shù)組元素?cái)?shù)大于實(shí)際存儲(chǔ)的數(shù)據(jù)以便增加和插入元素,它們都允許直接按序號(hào)索引元素,但是插入元素要涉及數(shù)組元素移動(dòng)等內(nèi)存操作,所以索引數(shù)據(jù)快而插入數(shù)據(jù)慢,Vector由于使用了synchronized 方法(線程安全),通常性能上較ArrayList 差,而LinkedList 使用雙向鏈表實(shí)現(xiàn)存儲(chǔ)(將內(nèi)存中零散的內(nèi)存單元通過(guò)附加的引用關(guān)聯(lián)起來(lái),形成一個(gè)可以按序號(hào)索引的線性結(jié)構(gòu),這種鏈?zhǔn)酱鎯?chǔ)方式與數(shù)組的連續(xù)存儲(chǔ)方式相比,其實(shí)對(duì)內(nèi)存的利用率更高),按序號(hào)索引數(shù)據(jù)需要進(jìn)行前向或后向遍歷,但是插入數(shù)據(jù)時(shí)只需要記錄本項(xiàng)的前后項(xiàng)即可,所以插入速度較快。Vector屬于遺留容器(早期的JDK中使用的容器,除此之外Hashtable、Dictionary、BitSet、Stack、Properties都是遺留容器),現(xiàn)在已經(jīng)不推薦使用,但是由于ArrayList和LinkedListed都是非線程安全的,如果需要多個(gè)線程操作同一個(gè)容器,那么可以通過(guò)工具類Collections中的synchronizedList方法將其轉(zhuǎn)換成線程安全的容器后再使用(這其實(shí)是裝潢模式最好的例子,將已有對(duì)象傳入另一個(gè)類的構(gòu)造器中創(chuàng)建新的對(duì)象來(lái)增加新功能)。
補(bǔ)充:遺留容器中的Properties類和Stack類在設(shè)計(jì)上有嚴(yán)重的問(wèn)題,Properties是一個(gè)鍵和值都是字符串的特殊的鍵值對(duì)映射,在設(shè)計(jì)上應(yīng)該是關(guān)聯(lián)一個(gè)Hashtable并將其兩個(gè)泛型參數(shù)設(shè)置為String類型,但是Java API中的Properties直接繼承了Hashtable,這很明顯是對(duì)繼承的濫用。這里復(fù)用代碼的方式應(yīng)該是HAS-A關(guān)系而不是IS-A關(guān)系,另一方面容器都屬于工具類,繼承工具類本身就是一個(gè)錯(cuò)誤的做法,使用工具類最好的方式是HAS-A關(guān)系(關(guān)聯(lián))或USE-A關(guān)系(依賴) 。同理,Stack類繼承Vector也是不正確的。?
由于字?jǐn)?shù)限制,后續(xù)內(nèi)容更加精彩,歡迎關(guān)注,整理不易,可否動(dòng)動(dòng)你的小手給小編來(lái)點(diǎn)更新的動(dòng)力,希望對(duì)你們會(huì)有幫助!~