Java程序员从笨鸟到菜鸟之(四)java开发常用类(包装,数字处理集合等)(上)
本文來自:曹勝歡博客專欄。轉載請注明出處:http://blog.csdn.NET/csh624366188
?
一:首談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,等等。?
所謂拆箱,就是跟裝箱的方向相反,將Integer及Double這樣的引用類型的對象重新簡化為值類型的數據?
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種,"=="是比較object的reference而不是value,自動裝箱后,abcd都是Integer這個Oject,因此“==”比較的是其引用。按照常規思維,1和3都應該輸出false。但結果是:?
true?
true?
false?
true
結果2和4,是因為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類中有一個數組緩存?了值從-128到127的Integer對象。當我們調用Integer.valueOf(int?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了!!!?
二:進軍集合類
集合其實就是存放對象的容器,專業點說就是集合是用來存儲和管理其他對象的對象,即對象的容器。集合可以擴容,長度可變,可以存儲多種類型的數據,而數組長度不可變,只能存儲單一類型的元素
用一張圖來總結一下集合的總況:
下面是網上找的一個圖片:
集合中的結構和幾個實現類:
總述:List、Set、Map是這個集合體系中最主要的三個接口。
其中List和Set繼承自Collection接口。
Set不允許元素重復。HashSet和TreeSet是兩個主要的實現類。
List有序且允許元素重復。ArrayList、LinkedList和Vector是三個主要的實現類。
???Map也屬于集合系統,但和Collection接口不同。Map是key對value的映射集合,其中key列就是一個集合。key不能重復,但是value可以重復。HashMap、TreeMap和Hashtable是三個主要的實現類。
???SortedSet和SortedMap接口對元素按指定規則排序,SortedMap是對key列進行排序。
具體來說:
1.Collection?接口用于表示任何對象或元素組。想要盡可能以常規方式處理一組元素時,就使用這一接口。
操作:
(1)?單元素添加、刪除操作:
boolean?add(Object?o):將對象添加給集合
boolean?remove(Object?o):?如果集合中有與o相匹配的對象,則刪除對象o
(2)?查詢操作:
int?size()?:返回當前集合中元素的數量
boolean?isEmpty()?:判斷集合中是否有任何元素
boolean?contains(Object?o)?:查找集合中是否含有對象o
Iterator?iterator()?:返回一個迭代器,用來訪問集合中的各個元素
(3)?組操作?:作用于元素組或整個集合
boolean?containsAll(Collection?c):?查找集合中是否含有集合c?中所有元素
boolean?addAll(Collection?c)?:?將集合c?中所有元素添加給該集合
void?clear():?刪除集合中所有元素
void?removeAll(Collection?c)?:?從集合中刪除集合c?中的所有元素
void?retainAll(Collection?c)?:?從集合中刪除集合c?中不包含的元素
(4)?Collection轉換為Object數組?:
Object[]?toArray()?:返回一個內含集合所有元素的array
Object[]?toArray(Object[]?a)?:返回一個內含集合所有元素的array。運行期返回的array和參數a的型別相同,需要轉換為正確型別。
此外,您還可以把集合轉換成其它任何其它的對象數組。但是,您不能直接把集合轉換成基本數據類型的數組,因為集合必須持有對象。
“斜體接口方法是可選的。因為一個接口實現必須實現所有接口方法,調用程序就需要一種途徑來知道一個可選的方法是不是不受支持。如果調用一種可選方法?時,一個?UnsupportedOperationException?被拋出,則操作失敗,因為方法不受支持。此異常類繼承?RuntimeException?類,避免了將所有集合操作放入?try-catch?塊。”
Collection不提供get()方法。如果要遍歷Collectin中的元素,就必須用Iterator。
2.List接口對Collection進行了簡單的擴充,它的具體實現類常用的有ArrayList和LinkedList。你可以將任何東西放到一個?List容器中,并在需要時從中取出。ArrayList從其命名中可以看出它是一種類似數組的形式進行存儲,因此它的隨機訪問速度極快,而?LinkedList的內部實現是鏈表,它適合于在鏈表中間需要頻繁進行插入和刪除操作。在具體應用時可以根據需要自由選擇。前面說的Iterator只?能對容器進行向前遍歷,而ListIterator則繼承了Iterator的思想,并提供了對List進行雙向遍歷的方法。
(1)?面向位置的操作包括插入某個元素或?Collection?的功能,還包括獲取、除去或更改元素的功能。在?List?中搜索元素可以從列表的頭部或尾部開始,如果找到元素,還將報告元素所在的位置?:
void?add(int?index,?Object?element):?在指定位置index上添加元素element
boolean?addAll(int?index,?Collection?c):?將集合c的所有元素添加到指定位置index
Object?get(int?index):?返回List中指定位置的元素
int?indexOf(Object?o):?返回第一個出現元素o的位置,否則返回-1
int?lastIndexOf(Object?o)?:返回最后一個出現元素o的位置,否則返回-1
Object?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”
LinkedList類
LinkedList類添加了一些處理列表兩端元素的方法。
(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?當作一個堆棧、隊列或其它面向端點的數據結構。”
ArrayList類
ArrayList類封裝了一個動態再分配的Object[]數組。每個ArrayList對象有一個capacity。這個capacity表示存儲列表中元素的數組的容量。當元素添加到ArrayList時,它的capacity在常量時間內自動增加。
?在向一個ArrayList對象添加大量元素的程序中,可使用ensureCapacity方法增加capacity。這可以減少增加重分配的數量。
?(1)?void?ensureCapacity(int?minCapacity):?將ArrayList對象容量增加minCapacity
(2)?void?trimToSize():?整理ArrayList對象容量為列表當前大小。程序可使用這個操作減少ArrayList對象存儲空間。
?本文來自:曹勝歡博客專欄。轉載請注明出處:http://blog.csdn.Net/csh624366188
總結
以上是生活随笔為你收集整理的Java程序员从笨鸟到菜鸟之(四)java开发常用类(包装,数字处理集合等)(上)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java程序员从笨鸟到菜鸟之(二十八)J
- 下一篇: Java程序员从笨鸟到菜鸟之(五)jav