作者: 一字馬胡
作為Java語言的重度使用者,很有必要認(rèn)識一下Java語言的通用技術(shù)棧堡纬。我非常喜歡運行于JVM之上的語言聂受,比如Java、Scala等烤镐,其中一個重要的原因在于JVM的GC機制蛋济,使得使用運行與JVM的各種的語言的時候不需要過于關(guān)注內(nèi)存管理方面的內(nèi)容,當(dāng)然炮叶,對于一些特殊場景下碗旅,內(nèi)存管理也是必不可少的,特別是對于一些對性能要求極高的應(yīng)用镜悉,但是祟辟,在極大概率下,我們在寫代碼的時候是不需要關(guān)心內(nèi)存管理方面的問題的侣肄。當(dāng)然旧困,除了GC之外,高性能也是我喜歡使用運行于JVM之上的語言的另外一大原因稼锅,比如Java語言吼具,性能和直接編譯為機器碼的語言比如C++不相上下,而在工程效率方面矩距,Java又是具有極大優(yōu)勢的一門語言拗盒,開發(fā)效率極高,說到開發(fā)效率锥债,就得說一下我喜歡Java語言的第三大原因了陡蝇,那就是Java生態(tài)的豐富性,經(jīng)過多年的發(fā)展赞弥,Java語言幾乎在各種場景下都有成熟的解決方案毅整,比如在Web方向上,有Spring生態(tài)绽左,在大數(shù)據(jù)領(lǐng)域,有Hadoop艇潭、spark拼窥、flink等一系列成熟的處理框架戏蔑,所以,無論在什么時候鲁纠,在做技術(shù)語言選型的時候总棵,Java總是應(yīng)該被優(yōu)先考慮。
因為Java技術(shù)體系的極大豐富性改含,所以情龄,在學(xué)習(xí)的時候就不得不選擇一些適合與各自領(lǐng)域的、或者感興趣的內(nèi)容去學(xué)習(xí)了捍壤,本文算是一種對近一年來使用Java語言的總結(jié)骤视,也是對未來學(xué)習(xí)和使用Java的一種規(guī)劃,我個人的興趣點在Web開發(fā)鹃觉、DataFlow专酗、高性能、高并發(fā)等內(nèi)容上盗扇,所以祷肯,本文所展示的技術(shù)棧都將和這些內(nèi)容相關(guān),但未來會逐漸添加一些新的技術(shù)方向疗隶,畢竟技術(shù)在不斷的升級優(yōu)化佑笋,新的技術(shù)也將不斷出現(xiàn)來取代老的技術(shù),當(dāng)然斑鼻,對于后端領(lǐng)域允青,技術(shù)的推陳出新似乎不會那么快速(和大前端相比),一個原因是后端需要提供穩(wěn)定有保障卵沉、高性能的服務(wù)颠锉,而新的技術(shù)可能僅僅滿足生產(chǎn)環(huán)境的一個或者幾個條件,還有待有一些能力較強史汗,愿意冒險的技術(shù)人員嘗試檢驗琼掠,之后才能逐漸被人們接收,但是停撞,這個過程是很漫長的瓷蛙,并且很多新的技術(shù)在這個過程中將會被淹沒。
下面戈毒,將會由淺入深的羅列我所知道的Java技術(shù)棧內(nèi)容艰猬,會用一些簡短有力的語言來描述具體的內(nèi)容,并且會羅列出一些參考資料埋市,以便未來不時之需可以拿來做參考冠桃。
Java 語言基礎(chǔ)內(nèi)容
語法及語言特性
第一部分首當(dāng)其沖就是Java語言基礎(chǔ),包括非常細(xì)節(jié)的Java語法道宅,也就是怎么使用Java語言來寫代碼食听,可能會覺得這個內(nèi)容很簡單胸蛛,任何一個有計算機基礎(chǔ)的人幾個小時之內(nèi)就可以學(xué)會使用Java語言來寫出具有一定功能的代碼,但是基礎(chǔ)永遠(yuǎn)是決定你可以在這門語言上能有多大造詣的關(guān)鍵性因素樱报。對于同一個功能葬项,可以不同的代碼來實現(xiàn),但是迹蛤,在極端情況下民珍,可能有些代碼就會表現(xiàn)得非常差勁,甚至?xí)l(fā)生不可扭轉(zhuǎn)的錯誤盗飒。
另外一點嚷量,Java語言是面向?qū)ο蟮母呒壵Z言,需要在學(xué)習(xí)和使用Java語言的時候去體會箩兽,并且使用這種思想去編程津肛,需要你對Java語言的特性有足夠的了解,比如Java是否支持多繼承汗贫,如何實現(xiàn)多繼承身坐,泛型技術(shù)等。
在學(xué)習(xí)Java語言基礎(chǔ)這點上落包,推薦閱讀經(jīng)典的《Java編程思想》部蛇,需要多看幾遍,并且下意識的去完成章節(jié)后面的練習(xí)咐蝇,會有很大的收獲涯鲁。下面是一些需要關(guān)注的點,后面的內(nèi)容中對下面的內(nèi)容會做更全面的說明:
訪問權(quán)限(private有序、protected抹腿、public、package-private)
需要關(guān)注每個權(quán)限的限定范圍旭寿,為什么需要有訪問控制警绩,怎么在實際應(yīng)用中正確的使用合適的訪問權(quán)限,這屬于比較基礎(chǔ)的內(nèi)容盅称,也是比較簡單的肩祥,但是正確的使用權(quán)限控制是一件不太容易的事情,這需要對代碼結(jié)構(gòu)設(shè)計缩膝、代碼風(fēng)格乃至設(shè)計模式都有所了解混狠。
-
多態(tài)
什么是多態(tài)?Java怎么實現(xiàn)多態(tài)的疾层?為什么需要多態(tài)将饺?如何使用Java實現(xiàn)多態(tài)?這幾個問題是用來檢測是否掌握了多態(tài)的問題,簡單來說俯逾,所謂多態(tài)贸桶,也就是同一套接口舅逸,有不同的實現(xiàn)類桌肴,這樣,同樣是調(diào)用接口的同一個方法琉历,但是不同的實現(xiàn)類就會有截然不同的表現(xiàn)坠七,但是多態(tài)的細(xì)節(jié)還需要深入學(xué)習(xí)總結(jié),多態(tài)的價值在于抽象旗笔,對于具有相同表現(xiàn)能力的對象進(jìn)行抽象彪置,然后不同的對象進(jìn)行不同的實現(xiàn),當(dāng)然蝇恶,說多態(tài)的價值在于抽象這種說明并不嚴(yán)謹(jǐn)或者正確拳魁,因為作為面向?qū)ο笏枷氲娜筇匦裕橄蟠榛 ⒗^承和多態(tài)是相輔相成的潘懊,抽象是設(shè)計技巧,繼承則是純技術(shù)性的特性贿衍,而多態(tài)將抽象和繼承結(jié)合起來授舟,這才是重點。
-
接口
接口是非常重要的類型抽象贸辈,所謂接口释树,就是抽象出一組方法,沒有方法實現(xiàn)擎淤,具體的方法實現(xiàn)需要子類自己去實現(xiàn)奢啥,接口用于向外部暴露出自己的服務(wù)能力,告訴調(diào)用者服務(wù)具有的能力嘴拢,而某個方法的具體實現(xiàn)則可以有多種多樣不同的形式桩盲,接口使用interface關(guān)鍵字來定義,和接口類似的是抽象類炊汤,抽象類使用abstract關(guān)鍵字來限定類正驻,當(dāng)然,抽象類和接口都是無法實例化的抢腐,都需要實例化其子類(實現(xiàn)類)姑曙,抽象類可以有一些通用方法的實現(xiàn),對于有個性化需求的方法迈倍,可以抽象為抽象方法伤靠,供子類實現(xiàn),抽象類經(jīng)常用于實現(xiàn)模板設(shè)計模式,抽象類和接口的本質(zhì)是抽象宴合,只不過接口相當(dāng)于所有方法都是抽象的焕梅,而抽象類中可以有具體的實現(xiàn)方法。
-
內(nèi)部類卦洽、嵌套類
所謂內(nèi)部類贞言,就是將一個類的定義放到了另外一個類里面,嵌套類則是靜態(tài)內(nèi)部類阀蒂,內(nèi)部類可以訪問外圍類的所有成員而不需要特殊的條件该窗,而且不管嵌套基層,這種特性依然生效蚤霞。靜態(tài)內(nèi)部類則相當(dāng)于一個獨立的類酗失,它只是被放到了一個外圍類內(nèi)部,并且在new一個靜態(tài)內(nèi)部類的對象的時候需要帶上外圍類作為前綴才行昧绣,靜態(tài)內(nèi)部類不能像內(nèi)部類一樣訪問外圍類规肴,它只能范圍外圍類中的靜態(tài)成員。內(nèi)部類的價值在于實現(xiàn)多重繼承夜畴,Java語言本身是不支持多重繼承的(單一繼承)拖刃,當(dāng)然,如果想實現(xiàn)多重繼承的效果斩启,可以使用實現(xiàn)多個接口的方式序调,內(nèi)部類也可以用于實現(xiàn)多重繼承的效果。
-
枚舉
在java中使用enum來定義一個枚舉類型兔簇,所謂枚舉发绢,就是一些固定的常量,比如顏色垄琐,則使用枚舉可以定義紅色边酒、白色、黑色等狸窘,當(dāng)需要表示一種顏色的時候墩朦,可以使用該枚舉類型去表示。當(dāng)然翻擒,如果僅僅是這樣氓涣,那么枚舉存在的意義似乎不是很大,使用類似‘static final int XXX = XXX’這樣也可以達(dá)到枚舉的效果陋气,無法就是定義一些常量劳吠,然后使用不同的常量值表示不同的枚舉值而已。在java中巩趁,枚舉類型是一種非常強大的類型 痒玩,你可以在枚舉類中添加方法,就像在普通類中那樣,需要知道的是蠢古,任何使用enum定義的枚舉類型奴曙,編譯器會自動為你生成一個集成java.lang.Enum的類,而java是單繼承的草讶,所以你不能繼承一個枚舉類型洽糟,但是你可以將枚舉類型放在一個接口里面,然后接口里面的枚舉實現(xiàn)接口到涂,并且進(jìn)行擴展脊框,這樣就實現(xiàn)了繼承枚舉類型的效果颁督。枚舉還有一些高級的用法践啄,比如使用枚舉來實現(xiàn)線程安全的單例模式,狀態(tài)機沉御、責(zé)任鏈等屿讽,使用枚舉會使得我們的代碼更加漂亮,學(xué)習(xí)枚舉以及掌握枚舉類型是非常有必要的吠裆,后面會進(jìn)行更為豐富的學(xué)習(xí)與總結(jié)伐谈。
-
注解
在開發(fā)過程中時常會碰到注解,注解是一種標(biāo)記试疙,比如@Override注解標(biāo)記一個方法是覆蓋方法诵棵,我們可以定義自己的注解,并且可以基于注解做一些處理祝旷,注解(Annotation)信息攜帶在對象的Class信息中履澳,可以在Class信息中找到對象所屬類型的注解信息,一個類可以有注解怀跛,一個字段也可以有注解距贷,在Spring開發(fā)中就有字段注解。
-
異常處理
這是一個沉重的話題吻谋,但是又不得不提一下忠蝗,異常處理系統(tǒng)是java語言中至關(guān)重要的一部分,正確的拋出異常漓拾,處理異常是非常重要的阁最,恰當(dāng)?shù)漠惓?梢暂o助解決問題骇两,而不恰當(dāng)?shù)膯栴}使得出現(xiàn)問題的時候百思不得其解速种。
-
數(shù)組
想象一下不支持?jǐn)?shù)組的編程語言是一種怎么樣的存在,我至今沒有接觸過不支持?jǐn)?shù)組類型的編程語言脯颜,這也說明數(shù)組這種類型是一種非常重要的類型哟旗,在java中,反而我們使用數(shù)組的時間并不多,而List闸餐、Set之類的容器成了首選饱亮,當(dāng)然,ArrayList是使用最為頻繁的容器舍沙,內(nèi)部依然是一個數(shù)組近上。其次,在java中拂铡,數(shù)組也是對象壹无,你可以使用數(shù)組和null值做比較判斷,但是數(shù)組是一種神奇的對象感帅,至于怎么神奇斗锭,需要日后專門探索一下。關(guān)鍵的內(nèi)容為數(shù)組的結(jié)構(gòu)失球,以及怎么使用數(shù)組等岖是。
-
集合
對象的容器,List实苞、Set豺撑、Map,盡管研究去吧黔牵,從線程不安全的集合到線程安全的集合聪轿,jdk中關(guān)于集合的內(nèi)容很多,也很值得仔細(xì)研究猾浦,比如ArrayList是在嗯么實現(xiàn)的陆错,具體實現(xiàn)的細(xì)節(jié)比如怎么實現(xiàn)擴容的,為什么不支持多線程跃巡,怎么樣使得ArrayList支持多線程等危号。又比如HashMap是怎么實現(xiàn)的,各個版本的區(qū)別又是什么素邪,為什么要改成現(xiàn)在這樣的結(jié)構(gòu)等等外莲。
-
字符串
String是一種java中最為頻繁使用的類型,它足夠簡單兔朦,你可以隨意使用偷线,并且提供了足夠多的方法來進(jìn)行字符串處理,但另外一方面沽甥,它又足夠復(fù)雜声邦,總之,學(xué)會使用以及研究它的本質(zhì)是非常值得的一件事情摆舟。
-
反射技術(shù)
反射就是在運行時可以獲取到一個類的方法亥曹、字段信息的一種技術(shù)邓了,這種技術(shù)非常有用。
-
泛型技術(shù)
泛型技術(shù)使得Object可以暫時不用代替“所有類型”了媳瞪!
-
IO骗炉、NIO、AIO蛇受、文件操作(Files)
網(wǎng)絡(luò)編程(socket編程)句葵,文件讀寫等內(nèi)容。
-
并發(fā)
jdk并發(fā)包中的內(nèi)容兢仰。
-
AST
java抽象語法樹乍丈。
JDK類庫
Java語言提供了一套非常友好的API給開發(fā)者使用,稱為JDK把将,作為Java開發(fā)者轻专,需要熟練使用JDK來做日常開發(fā),JDK中的實現(xiàn)是經(jīng)過大量優(yōu)化的實現(xiàn)秸弛,所以無論是性能還是安全等都是頂級水準(zhǔn)铭若,所以,如果一個功能JDK提供了递览,那就使用JDK提供的,比如很重要的一個功能是數(shù)據(jù)排序瞳腌,JDK提供了相應(yīng)的API來供你做排序绞铃,并且是經(jīng)過優(yōu)化的,所以嫂侍,就不要試圖實現(xiàn)什么快速排序算法來對你的數(shù)據(jù)排序(這也可以儿捧,但是費工時,最后效果還沒有JDK提供的好)挑宠。
JDK會隨著Java語言的升級而升級菲盾,會逐漸豐富整個類庫,也會根據(jù)語言特性新增一些和語言特性相關(guān)的API各淀。推薦使用JDK1.7及以上的版本用于實際開發(fā)懒鉴,本文將使用JDK1.8來進(jìn)行描述。
下面將對幾個常用的JDK類庫進(jìn)行描述碎浇,JDK類庫非常豐富临谱,在日常開發(fā)中可能僅僅使用了JDK中一個非常小的子集,所以奴璃,如果對某些部分感興趣悉默,需要自己去探索發(fā)現(xiàn)。
JDK類庫-基本類型
類型包括基本數(shù)據(jù)類型和包裝數(shù)據(jù)類型苟穆,基本數(shù)據(jù)類型包括int抄课、long唱星、float、double跟磨、boolean魏颓、short、char等吱晒,包裝數(shù)據(jù)類型就是對基本類型的包裝甸饱,比如int的包裝類型為Integer,long的包裝類型為Long仑濒,需要注意的一點是叹话,基本類型的默認(rèn)值和包裝類型的默認(rèn)值是不一樣的,比如int的默認(rèn)值可能為0墩瞳,但是Integer的默認(rèn)值是null(因為是對象)驼壶,所以在使用的時候就要注意空指針的問題了。
關(guān)于數(shù)據(jù)類型喉酌,可能沒什么需要多說的热凹,但是還是需要特別說明一下,基本數(shù)據(jù)類型的包裝類型都有一些靜態(tài)方法來將基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類型泪电,這些方法以"valueOf"般妙,"parseXXX"開頭,很容易識別相速。
JDK類庫-集合
集合在java.util包下碟渺,需要說明的一點是,java.util包下都是好東西突诬,包括集合苫拍、Stream、并發(fā)等一系列內(nèi)容旺隙,屬于JDK的精品部分绒极,這個包也是日常開發(fā)中使用頻率比較高的一個。
上面的圖片展示了Java集合的類圖關(guān)系蔬捷,我們需要關(guān)注的有這么幾個垄提,List、Set抠刺、Map塔淤,這是三個接口,List是線性表速妖,Set是集合高蜂,Map是鍵值對映射容器,這三種容器適用場景是不一樣的罕容,對于List备恤,它常用的實現(xiàn)類有ArrayList稿饰、LinkedList,List是一種通用容器露泊,可以存儲對象喉镰,ArrayList適用于讀寫少的場景,而LinkedList適用與寫多讀少的場景惭笑,ArrayList內(nèi)部使用數(shù)組來實現(xiàn)侣姆,LinkedList內(nèi)部使用鏈表來實現(xiàn)。Set和List的區(qū)別在于List中存儲的對象可以重復(fù)沉噩,但是Set容器中每個對象只能存儲一份捺宗,如果已經(jīng)有一份,那么是存儲不進(jìn)去的川蒙,Set的實現(xiàn)類有HashSet和TreeSet蚜厉。HashSet內(nèi)部使用HashMap實現(xiàn),而TreeSet內(nèi)部使用TreeMap實現(xiàn)畜眨。Set的存儲對象唯一性這種特性適合用于判斷一個對象是否存在于容器中這樣的場景昼牛,需要注意的是,List也可以實現(xiàn)這種“是否存在”的語義判斷康聂,但是List和Set實現(xiàn)的方法是不一樣的贰健,復(fù)雜度也是不可同日而語的,List實現(xiàn)同樣功能的時間復(fù)雜度是O(N)早抠,而Set則是O(1)霎烙。下面是ArrayList和HashSet實現(xiàn)同樣功能的代碼展示:
ArrayList:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
HashSet:
public boolean containsKey(Object key) {
return getNode(hash(key), key) != null;
}
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
if ((tab = table) != null && (n = tab.length) > 0 &&
(first = tab[(n - 1) & hash]) != null) {
if (first.hash == hash && // always check first node
((k = first.key) == key || (key != null && key.equals(k))))
return first;
if ((e = first.next) != null) {
if (first instanceof TreeNode)
return ((TreeNode<K,V>)first).getTreeNode(hash, key);
do {
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
} while ((e = e.next) != null);
}
}
return null;
}
可以看到,ArrayList遍歷了一次數(shù)組蕊连,然后逐一判斷,但是HashSet則使用Map的containsKey方法來判斷是否存在游昼,而這個復(fù)雜度大概率是接近O(1)的甘苍。接下來就說Map,這是一種存儲鍵值對映射的容器烘豌,常用的Map的實現(xiàn)類包括HashMap载庭,LinkedHashMap,TreeMap廊佩,SortdMap囚聚,最常用的是HashMap。TreeMap內(nèi)部還有紅黑樹實現(xiàn)标锄,而SortedMap則提供排序功能顽铸。還有兩種重要的數(shù)據(jù)結(jié)構(gòu)Queue和Stack,在實際項目中料皇。如果想使用Queue和Stack谓松,一般使用LinkedList來實現(xiàn)星压,LinkedList是一個使用雙向鏈表存儲數(shù)據(jù)的結(jié)構(gòu),可以實現(xiàn)具有FIFO性質(zhì)的Queue和FILO性質(zhì)的Stack鬼譬,下面是一個使用LinkedList來實現(xiàn)Stack功能的參考娜膘,對于Queue也是類似的:
import java.util.LinkedList;
public class WrapStack<T> {
private LinkedList<T> stack;
public WrapStack() {
this.stack = new LinkedList<>();
}
public T pop() {
if (stack == null) {
stack = new LinkedList<>();
return null;
} else {
return stack.removeFirst();
}
}
public void push(T data) {
if (this.stack == null) {
this.stack = new LinkedList<>();
}
if (data == null) {
throw new NullPointerException("The input data must bot null");
}
this.stack.addFirst(data);
}
public boolean isEmpty() {
return this.stack == null || this.stack.isEmpty();
}
public int size() {
if (this.stack == null) {
return 0;
} else {
return this.stack.size();
}
}
}
掌握了這些常用的數(shù)據(jù)容器之后,接下來就需要了解兩個特別重要和實用的和集合相關(guān)的util類:Collections和Arrays优质。
先說Collections竣贪,Collections包含大量的操作容器的靜態(tài)方法,比如排序巩螃、拷貝演怎、查找、反轉(zhuǎn)牺六、求min/max颤枪、比較、計數(shù)淑际、shuffle畏纲、check,swap等等春缕,所以幾乎你可以想到的操作集合的op都在里面可以找到盗胀,可以說是百寶箱了,但是在實際操作中锄贼,因為我們可能并不知道這些實用方法確實已經(jīng)存在票灰,所以可能有時候會自己去造輪子,一方面造輪子是比較費時的宅荤,另外一方面對于一些基礎(chǔ)功能屑迂,需要做足夠的測試,包括正確性驗證和性能測試冯键,必要的時候還需要做性能優(yōu)化巡雨,整體來說是一件很耗費精力的事情陆赋,如果我們知道了這些實用方法的存在干花,那么在遇到需要某些功能的時候蜈亩,就會下意識的到這里面來找找是不是已經(jīng)存在對應(yīng)的方法畅涂,如果沒有午衰,那么再自己去寫尊流。比如如果需要在集合中查找一個元素是否存在逻住,那么可以使用Collections提供的二分查找算法:
public static <T>
int binarySearch(List<? extends Comparable<? super T>> list, T key) {
if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
return Collections.indexedBinarySearch(list, key);
else
return Collections.iteratorBinarySearch(list, key);
}
private static <T>
int indexedBinarySearch(List<? extends Comparable<? super T>> list, T key) {
int low = 0;
int high = list.size()-1;
while (low <= high) {
int mid = (low + high) >>> 1;
Comparable<? super T> midVal = list.get(mid);
int cmp = midVal.compareTo(key);
if (cmp < 0)
low = mid + 1;
else if (cmp > 0)
high = mid - 1;
else
return mid; // key found
}
return -(low + 1); // key not found
}
...
在日常開發(fā)中扒秸,使用Collections中最為頻繁的功能當(dāng)屬獲取一個不可變集合類型翼闽,比如返回一個不可變的List选浑,一個不可變的Map等拓提,可以使用Collections.emptyList(),Collections.emptySet(),Collections.emptyMap()等來實現(xiàn)。
接著,說完Collections,再來說說Arrays,Collections是專門為操作集合設(shè)計的,而Arrays是為數(shù)組設(shè)計的,為數(shù)組提供一系列便捷的操作,比如排序黄痪、查找等挺尾,當(dāng)然魂挂,還可以將數(shù)組方便的轉(zhuǎn)換成一個新的List,這樣就可以使用Collections來操作了涂召。記住一點坠非,所有你能想到的對于數(shù)組的操作,首先去Arrays看看有沒有現(xiàn)成的方法芹扭,如果有麻顶,那么使用現(xiàn)有的,如果沒有再自己實現(xiàn)舱卡「ㄉ觯可以看到,Arrays提供了大量的sort/search/fill/copy方法轮锥,甚至可以將數(shù)組直接轉(zhuǎn)換成一個新的Stream矫钓,那樣就可以使用Stream的一系列便捷方法來操作數(shù)組了。
總結(jié):JAVA集合使用到的頻率是非常高的舍杜,對List新娜、Set、Map的常用實現(xiàn)類需要熟練掌握使用場景既绩、使用方法等內(nèi)容概龄,當(dāng)有對集合操作的需求的時候,首先想到的應(yīng)該是實現(xiàn)類自身的方法成員饲握,然后就是Collections里面提供的方法私杜,對于數(shù)組,如果需要對數(shù)組進(jìn)行排序救欧、查找衰粹、初始化等操作的時候,首先應(yīng)該使用Arrays里面提供的方法笆怠,如果不能滿足需求铝耻,再去尋求其他的方案來實現(xiàn)。