1. 程式人生 > >Java程式設計師從笨鳥到菜鳥之(四)java開發常用類(包裝,數字處理集合等)(上)

Java程式設計師從笨鳥到菜鳥之(四)java開發常用類(包裝,數字處理集合等)(上)

               

一:首談java中的包裝類

     Java為基本型別提供包裝類,這使得任何接受物件的操作也可以用來操作基本型別,直接將簡單型別的變量表示為一個類,在執行變數型別的相互轉換時,我們會大量使用這些包裝類。java是一種面嚮物件語言,java中的類把方法與資料連線在一起,並構成了自包含式的處理單元.但在java中不能定義基本型別(primitive type),為了能將基本型別視為物件來處理,並能連線相關的方法,java為每個基本型別都提供了包裝類,這樣,我們便可以把這些基本型別轉化為物件來處理了.這些包裝類有:Boolean,Byte,Short,Character,Integer,Long,Float,Void

值得說明的是,java是可以直接處理基本型別的,但是在有些情況下我們需要將其作為物件來處理,這時就需要將其轉化為包裝類了.所有的包裝類(Wrapper Class)都有共同的方法,他們是:

(1)帶有基本值引數並建立包裝類物件的建構函式.如可以利用Integer   裝類建立物件,Integer obj=new Integer(145);

(2)帶有字串引數並建立包裝類物件的建構函式.new Integer("45");

(3)生成字串表示法的toString()方法,obj.toString().

(4)對同一個類的兩個物件進行比較的equals()方法,obj1.eauqls(obj2);

(5)生成哈稀表程式碼的hashCode方法,obj.hasCode();

(6)將字串轉換為基本值的 parseType方法,Integer.parseInt(args[0]);

(7)可生成物件基本值的typeValue方法,obj.intValue();

在一定的場合,運用java包裝類來解決問題,能大大提高程式設計效率.

包裝類的自動裝箱,自動拆箱

所謂裝箱,就是把基本型別用它們相對應的引用型別包起來,使它們可以具有物件的特質,如我們可以把int型包裝成Integer類的物件,或者把double包裝成Double,等等。 所謂拆箱,就是跟裝箱的方向相反,將IntegerDouble這樣的引用型別的物件重新簡化為值型別的資料 

javaSE5.0後提供了自動裝箱與拆箱的功能,此功能事實上是編譯器來幫您的忙,編譯器在編譯時期依您所編寫的方法,決定是否進行裝箱或拆箱動作。 自動裝箱的過程:每當需要一種型別的物件時,這種基本型別就自動地封裝到與它相同型別的包裝中。 自動拆箱的過程:每當需要一個值時,被裝箱物件中的值就被自動地提取出來,沒必要再去呼叫intValue()doubleValue()方法。 自動裝箱,只需將該值賦給一個型別包裝器引用,java會自動建立一個物件。例如:Integer i=100;//沒有通過使用new來顯示建立,java自動完成。 

自動拆箱,只需將該物件值賦給一個基本型別即可,例如

· int i = 11;  

· Integer j = i; //自動裝箱  

· int k = j //自動拆箱 

然而在Integer的自動裝拆箱會有些細節值得注意:

public static void main(String[] args) {  

    Integer a=100;  

    Integer b=100;   

    Integer c=200;  

    Integer d=200;   

   System.out.println(a==b);   //1  

   System.out.println(a==100); //2     

  System.out.println(c==d);   //3  

  System.out.println(c==200); //4  

   }  在java種,"=="是比較objectreference而不是value,自動裝箱後,abcd都是Integer這個Oject,因此“==”比較的是其引用。按照常規思維,13都應該輸出false。但結果是: true true false true結果24,是因為ac進行了自動拆箱,因此其比較是基本資料型別的比較,就跟int比較時一樣的,“==”在這裡比較的是它們的值,而不是引用。 對於結果1,雖然比較的時候,還是比較物件的reference,但是自動裝箱時,java在編譯的時候 Integer a = 100; 被翻譯成-> Integer a = Integer.valueOf(100); 關鍵就在於這個valueOf()的方法。 

public static Integer valueOf(int i) {     

final int offset = 128;     

if (i >= -128 && i <= 127) { // must cache     

return IntegerCache.cache[i + offset];     

}     

return new Integer(i);     

}     

private static class IntegerCache {     

private IntegerCache(){}     

static final Integer cache[] = new Integer[-(-128) + 127 + 1];     

static {     

for(int i = 0; i < cache.length; i++)     

cache = new Integer(i - 128);     

}     

}   根據上面的jdk原始碼,java為了提高效率,IntegerCache類中有一個數組快取 了值從-128127Integer物件。當我們呼叫Integer.valueOfint i)的時候,如果i的值是>=-128<=127時,會直接從這個快取中返回一個物件,否則就new一個Integer物件。具體如下: 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; //cache[]變成靜態  

static {  

        for(int i = 0; i < cache.length; i++)  

        cache[i] = new Integer(i - 128); //初始化cache[i]  

}  這是用一個for迴圈對陣列cache賦值,cache[255] = new Integer(255-128),也就是newl一個Integer(127) ,並把引用賦值給cache[255],好了,然後是Integer b= 127,流程基本一樣,最後又到了cache[255] = new Integer(255-128),這一句,那我們迷糊了,這不是又new了一個物件127嗎,然後把引用賦值給cache[255],我們比較這兩個引 用(前面宣告a的時候也有一個),由於是不同的地址,所以肯定不會相等,應該返回false啊!呵呵,這麼想你就錯了,請注意看for語句給 cache[i]初始化的時候外面還一個{}呢,{}前面一個大大的static關鍵字,是靜態的,那麼我們就可以回想下static有什麼特性了,只能 初始化一次,在物件間共享,也就是不同的物件共享同一個static資料

。那麼當我們Integer b = 127的時候,並沒有new出一個新物件來,而是共享了a這個物件的引用,記住,他們共享了同一個引用!!!,那麼我們進行比較a==b時,由於是同一個物件的引用(她們在堆中的地址相同),那當然返回true了!!! 

二:進軍集合類

集合其實就是存放物件的容器,專業點說就是集合是用來儲存和管理其他物件的物件,即物件的容器。集合可以擴容,長度可變,可以儲存多種型別的資料,而陣列長度不可變,只能儲存單一型別的元素

用一張圖來總結一下集合的總況:

下面是網上找的一個圖片:

集合中的結構和幾個實現類:

總述:ListSetMap是這個集合體系中最主要的三個介面。其中ListSet繼承自Collection介面。Set不允許元素重複。HashSetTreeSet是兩個主要的實現類。List有序且允許元素重複。ArrayListLinkedListVector是三個主要的實現類。   Map也屬於集合系統,但和Collection介面不同。Mapkeyvalue的對映集合,其中key列就是一個集合。key不能重複,但是value可以重複。HashMapTreeMapHashtable是三個主要的實現類。   SortedSetSortedMap介面對元素按指定規則排序,SortedMap是對key列進行排序。

具體來說:

1.Collection 介面用於表示任何物件或元素組。想要儘可能以常規方式處理一組元素時,就使用這一介面。

操作:

(1) 單元素新增、刪除操作:boolean add(Object o):將物件新增給集合boolean remove(Object o): 如果集合中有與o相匹配的物件,則刪除物件o(2) 查詢操作:int size() :返回當前集合中元素的數量boolean isEmpty() :判斷集合中是否有任何元素boolean contains(Object o) :查詢集合中是否含有物件oIterator iterator() :返回一個迭代器,用來訪問集合中的各個元素(3) 組操作 :作用於元素組或整個集合boolean containsAll(Collection c): 查詢集合中是否含有集合中所有元素boolean addAll(Collection c) : 將集合中所有元素新增給該集合void clear(): 刪除集合中所有元素void removeAll(Collection c) : 從集合中刪除集合中的所有元素void retainAll(Collection c) : 從集合中刪除集合中不包含的元素(4) Collection轉換為Object陣列 :Object[] toArray() :返回一個內含集合所有元素的arrayObject[] toArray(Object[] a) :返回一個內含集合所有元素的array。執行期返回的array和引數a的型別相同,需要轉換為正確型別。此外,您還可以把集合轉換成其它任何其它的物件陣列。但是,您不能直接把集合轉換成基本資料型別的陣列,因為集合必須持有物件。“斜體介面方法是可選的。因為一個介面實現必須實現所有介面方法,呼叫程式就需要一種途徑來知道一個可選的方法是不是不受支援。如果呼叫一種可選方法 時,一個 UnsupportedOperationException 被丟擲,則操作失敗,因為方法不受支援。此異常類繼承 RuntimeException 類,避免了將所有集合操作放入 try-catch 塊。Collection不提供get()方法。如果要遍歷Collectin中的元素,就必須用Iterator

2.List介面Collection進行了簡單的擴充,它的具體實現類常用的有ArrayListLinkedList。你可以將任何東西放到一個 List容器中,並在需要時從中取出。ArrayList從其命名中可以看出它是一種類似陣列的形式進行儲存,因此它的隨機訪問速度極快,而 LinkedList的內部實現是連結串列,它適合於在連結串列中間需要頻繁進行插入和刪除操作。在具體應用時可以根據需要自由選擇。前面說的Iterator只 能對容器進行向前遍歷,而ListIterator則繼承了Iterator的思想,並提供了對List進行雙向遍歷的方法。

(1) 面向位置的操作包括插入某個元素或 Collection 的功能,還包括獲取、除去或更改元素的功能。在 List 中搜索元素可以從列表的頭部或尾部開始,如果找到元素,還將報告元素所在的位置 :void add(int index, Object element): 在指定位置index上新增元素elementboolean addAll(int index, Collection c): 將集合c的所有元素新增到指定位置indexObject get(int index): 返回List中指定位置的元素int indexOf(Object o): 返回第一個出現元素o的位置,否則返回-1int lastIndexOf(Object o) :返回最後一個出現元素o的位置,否則返回-1Object remove(int index) :刪除指定位置上的元素Object set(int index, Object element) :用元素element取代位置index上的元素,並且返回舊的元素(2) List 介面不但以位置序列迭代的遍歷整個列表,還能處理集合的子集:ListIterator listIterator() : 返回一個列表迭代器,用來訪問列表中的元素ListIterator listIterator(int index) : 返回一個列表迭代器,用來從指定位置index開始訪問列表中的元素List subList(int fromIndex, int toIndex) :返回從指定位置fromIndex(包含)到toIndex(不包含)範圍中各個元素的列表檢視對子列表的更改(如 add()remove() 和 set() 呼叫)對底層 List 也有影響。” “ArrayList 和 LinkedList 都實現 Cloneable 介面,都提供了兩個建構函式,一個無參的,一個接受另一個Collection”LinkedListLinkedList類添加了一些處理列表兩端元素的方法。(1) void addFirst(Object o): 將物件o新增到列表的開頭void addLast(Object o):將物件o新增到列表的結尾(2) Object getFirst(): 返回列表開頭的元素Object getLast(): 返回列表結尾的元素(3) Object removeFirst(): 刪除並且返回列表開頭的元素Object removeLast():刪除並且返回列表結尾的元素(4) LinkedList(): 構建一個空的連結列表LinkedList(Collection c): 構建一個連結列表,並且新增集合c的所有元素使用這些新方法,您就可以輕鬆的把 LinkedList 當作一個堆疊、佇列或其它面向端點的資料結構。ArrayListArrayList類封裝了一個動態再分配的Object[]陣列。每個ArrayList物件有一個capacity。這個capacity表示儲存列表中元素的陣列的容量。當元素新增到ArrayList時,它的capacity在常量時間內自動增加。 在向一個ArrayList物件新增大量元素的程式中,可使用ensureCapacity方法增加capacity。這可以減少增加重分配的數量。 (1) void ensureCapacity(int minCapacity): ArrayList物件容量增加minCapacity(2) void trimToSize(): 整理ArrayList物件容量為列表當前大小。程式可使用這個操作減少ArrayList物件儲存空間。