最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java中常用數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)類 Collection和Map

 更新時(shí)間:2016年09月02日 10:02:34   投稿:jingxian  
下面小編就為大家?guī)硪黄獪\談Java中常用數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)類 Collection和Map。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

線性表,鏈表,哈希表是常用的數(shù)據(jù)結(jié)構(gòu),在進(jìn)行Java開發(fā)時(shí),JDK已經(jīng)為我們提供了一系列相應(yīng)的類來實(shí)現(xiàn)基本的數(shù)據(jù)結(jié)構(gòu)。這些類均在java.util包中。本文試圖通過簡單的描述,向讀者闡述各個(gè)類的作用以及如何正確使用這些類。

Collection 
├List 
│├LinkedList 
│├ArrayList 
│└Vector 
│ └Stack 
└Set 
Map 
├Hashtable 
├HashMap 
└WeakHashMap 

Collection接口

Collection是最基本的集合接口,一個(gè)Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。

所有實(shí)現(xiàn)Collection接口的類都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)空的Collection,有一個(gè)Collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的Collection,這個(gè)新的Collection與傳入的Collection有相同的元素。后一個(gè)構(gòu)造函數(shù)允許用戶復(fù)制一個(gè)Collection。

如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何,它都支持一個(gè)iterator()的方法,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問Collection中每一個(gè)元素。

典型的用法如下:

Iterator it = collection.iterator(); // 獲得一個(gè)迭代子 
    while(it.hasNext()) { 
      Object obj = it.next(); // 得到下一個(gè)元素 
} 

由Collection接口派生的兩個(gè)接口是List和Set。 
 
List接口

List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來訪問List中的元素,這類似于Java的數(shù)組。

和下面要提到的Set不同,List允許有相同的元素。

除了具有Collection接口必備的iterator()方法外,List還提供一個(gè)listIterator()方法,返回一個(gè)ListIterator接口,和標(biāo)準(zhǔn)的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設(shè)定元素,還能向前或向后遍歷。

實(shí)現(xiàn)List接口的常用類有LinkedList,ArrayList,Vector和Stack。 
 
LinkedList類

LinkedList實(shí)現(xiàn)了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊(duì)列(queue)或雙向隊(duì)列(deque)。

注意LinkedList沒有同步方法。如果多個(gè)線程同時(shí)訪問一個(gè)List,則必須自己實(shí)現(xiàn)訪問同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List:

List list = Collections.synchronizedList(new LinkedList(...)); 
 
ArrayList類

ArrayList實(shí)現(xiàn)了可變大小的數(shù)組。它允許所有元素,包括null。ArrayList沒有同步。

size,isEmpty,get,set方法運(yùn)行時(shí)間為常數(shù)。但是add方法開銷為分?jǐn)偟某?shù),添加n個(gè)元素需要O(n)的時(shí)間。其他的方法運(yùn)行時(shí)間為線性。

每個(gè)ArrayList實(shí)例都有一個(gè)容量(Capacity),即用于存儲(chǔ)元素的數(shù)組的大小。這個(gè)容量可隨著不斷添加新元素而自動(dòng)增加,但是增長算法并沒有定義。當(dāng)需要插入大量元素時(shí),在插入前可以調(diào)用ensureCapacity方法來增加ArrayList的容量以提高插入效率。

和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。 
 
Vector類

Vector非常類似ArrayList,但是Vector是同步的。由Vector創(chuàng)建的Iterator,雖然和ArrayList創(chuàng)建的Iterator是同一接口,但是,因?yàn)閂ector是同步的,當(dāng)一個(gè)Iterator被創(chuàng)建而且正在被使用,另一個(gè)線程改變了Vector的狀態(tài)(例如,添加或刪除了一些元素),這時(shí)調(diào)用Iterator的方法時(shí)將拋出ConcurrentModificationException,因此必須捕獲該異常。 
 
Stack 類

Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧。Stack提供5個(gè)額外的方法使得Vector得以被當(dāng)作堆棧使用。基本的push和pop方法,還有peek方法得到棧頂?shù)脑?,empty方法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。 
 
Set接口

Set是一種不包含重復(fù)的元素的Collection,即任意的兩個(gè)元素e1和e2都有e1.equals(e2)=false,Set最多有一個(gè)null元素。

很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。

請(qǐng)注意:必須小心操作可變對(duì)象(Mutable Object)。如果一個(gè)Set中的可變?cè)馗淖兞俗陨頎顟B(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問題。 
 
Map接口

請(qǐng)注意,Map沒有繼承Collection接口,Map提供key到value的映射。一個(gè)Map中不能包含相同的key,每個(gè)key只能映射一個(gè)value。Map接口提供3種集合的視圖,Map的內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者一組key-value映射。 
 
Hashtable類

Hashtable實(shí)現(xiàn)Map接口,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的對(duì)象都可作為key或者value。

添加數(shù)據(jù)使用put(key, value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開銷為常數(shù)。

Hashtable通過initial capacity和load factor兩個(gè)參數(shù)調(diào)整性能。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,這會(huì)影響像get和put這樣的操作。

使用Hashtable的簡單示例如下,將1,2,3放到Hashtable中,他們的key分別是”one”,”two”,”three”:

Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));

要取出一個(gè)數(shù),比如2,用相應(yīng)的key:

Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);

由于作為key的對(duì)象將通過計(jì)算其散列函數(shù)來確定與之對(duì)應(yīng)的value的位置,因此任何作為key的對(duì)象都必須實(shí)現(xiàn)hashCode和equals方法。hashCode和equals方法繼承自根類Object,如果你用自定義的類當(dāng)作key的話,要相當(dāng)小心,按照散列函數(shù)的定義,如果兩個(gè)對(duì)象相同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個(gè)對(duì)象不同,則它們的hashCode不一定不同,如果兩個(gè)不同對(duì)象的hashCode相同,這種現(xiàn)象稱為沖突,沖突會(huì)導(dǎo)致操作哈希表的時(shí)間開銷增大,所以盡量定義好的hashCode()方法,能加快哈希表的操作。

如果相同的對(duì)象有不同的hashCode,對(duì)哈希表的操作會(huì)出現(xiàn)意想不到的結(jié)果(期待的get方法返回null),要避免這種問題,只需要牢記一條:要同時(shí)復(fù)寫equals方法和hashCode方法,而不要只寫其中一個(gè)。

Hashtable是同步的。 
 
HashMap類

HashMap和Hashtable類似,不同之處在于HashMap是非同步的,并且允許null,即null value和null key。,但是將HashMap視為Collection時(shí)(values()方法可返回Collection),其迭代子操作時(shí)間開銷和HashMap的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的話,不要將HashMap的初始化容量設(shè)得過高,或者load factor過低。 
 
WeakHashMap類

WeakHashMap是一種改進(jìn)的HashMap,它對(duì)key實(shí)行“弱引用”,如果一個(gè)key不再被外部所引用,那么該key可以被GC回收。 
 
總結(jié)

如果涉及到堆棧,隊(duì)列等操作,應(yīng)該考慮用List,對(duì)于需要快速插入,刪除元素,應(yīng)該使用LinkedList,如果需要快速隨機(jī)訪問元素,應(yīng)該使用ArrayList。

Java.util.Collections類包

java.util.Collections類包含很多有用的方法,可以使程序員的工作變得更加容易,但是這些方法通常都沒有被充分地利用。Javadoc給出Collections類最完整的描述:“這一個(gè)類包含可以操作或返回集合的專用靜態(tài)類。
” 1.2 所含方法
Iterator, ArrayList, Elements, Buffer, Map,Collections

列子:

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Collections; 
import java.util.Comparator; 
import java.util.List; 

public class CollectionsSort { 
public CollectionsSort() { 

} 

public static void main(String[] args) { 
double array[] = {111, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
List li = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
//list.add(""+array[i]); 
} 
double arr[] = {111}; 
for(int j=0;j<arr.length;j++){ 
li.add(new Double(arr[j])); 
} 
} 

2. 具體操作

1) 排序(Sort)

使用sort方法可以根據(jù)元素的自然順序?qū)χ付斜戆瓷蜻M(jìn)行排序。列表中的所有元素都必須實(shí)現(xiàn) Comparable 接口。此列表內(nèi)的所有元素都必須是使用指定比較器可相互比較的

double array[] = {112, 111, 23, 456, 231 }; 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections.sort(list); 
for (int i = 0; i < array.length; i++) { 
 System.out.println(li.get(i)); 
} 
//結(jié)果:112,111,23,456,231 

2) 混排(Shuffling)

混排算法所做的正好與 sort 相反: 它打亂在一個(gè) List 中可能有的任何排列的蹤跡。也就是說,基于隨機(jī)源的輸入重排該 List, 這樣的排列具有相同的可能性(假設(shè)隨機(jī)源是公正的)。這個(gè)算法在實(shí)現(xiàn)一個(gè)碰運(yùn)氣的游戲中是非常有用的。例如,它可被用來混排代表一副牌的 Card 對(duì)象的一個(gè) List 。另外,在生成測(cè)試案例時(shí),它也是十分有用的。

Collections.Shuffling(list) 
double array[] = {112, 111, 23, 456, 231 }; 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections.shuffle(list); 
for (int i = 0; i < array.length; i++) { 
 System.out.println(li.get(i)); 
} 
//結(jié)果:112,111,23,456,231 

3) 反轉(zhuǎn)(Reverse)

使用Reverse方法可以根據(jù)元素的自然順序?qū)χ付斜戆唇敌蜻M(jìn)行排序。

Collections.reverse(list) 
double array[] = {112, 111, 23, 456, 231 }; 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections. reverse (list); 
for (int i = 0; i < array.length; i++) { 
 System.out.println(li.get(i)); 
} 
//結(jié)果:231,456,23,111,112 
4) 替換所以的元素(Fill) 
使用指定元素替換指定列表中的所有元素。 
String str[] = {"dd","aa","bb","cc","ee"}; 
for(int j=0;j<str.length;j++){ 
li.add(new String(str[j])); 
} 
Collections.fill(li,"aaa"); 
for (int i = 0; i < li.size(); i++) { 
System.out.println("list[" + i + "]=" + li.get(i)); 

} 
//結(jié)果:aaa,aaa,aaa,aaa,aaa 

5) 拷貝(Copy)

用兩個(gè)參數(shù),一個(gè)目標(biāo) List 和一個(gè)源 List, 將源的元素拷貝到目標(biāo),并覆蓋它的內(nèi)容。目標(biāo) List 至少與源一樣長。如果它更長,則在目標(biāo) List 中的剩余元素不受影響。

Collections.copy(list,li): 后面一個(gè)參數(shù)是目標(biāo)列表 ,前一個(gè)是源列表

double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
List li = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
double arr[] = {1131,333}; 
String str[] = {"dd","aa","bb","cc","ee"}; 
for(int j=0;j<arr.length;j++){ 
li.add(new Double(arr[j])); 
} 
Collections.copy(list,li); 
for (int i = 0; i <list.size(); i++) { 
System.out.println("list[" + i + "]=" + list.get(i)); 
} 
//結(jié)果:1131,333,23,456,231 

6) 返回Collections中最小元素(min)

根據(jù)指定比較器產(chǎn)生的順序,返回給定 collection 的最小元素。collection 中的所有元素都必須是通過指定比較器可相互比較的

Collections.min(list) 
double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections.min(list); 
for (int i = 0; i <list.size(); i++) { 
System.out.println("list[" + i + "]=" + list.get(i)); 
} 
//結(jié)果:23 

7) 返回Collections中最小元素(max)

根據(jù)指定比較器產(chǎn)生的順序,返回給定 collection 的最大元素。collection 中的所有元素都必須是通過指定比較器可相互比較的

Collections.max(list) 
double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections.max(list); 
for (int i = 0; i <list.size(); i++) { 
System.out.println("list[" + i + "]=" + list.get(i)); 
} 
//結(jié)果:456 

8) lastIndexOfSubList

返回指定源列表中最后一次出現(xiàn)指定目標(biāo)列表的起始位置

int count = Collections.lastIndexOfSubList(list,li); 
double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
List li = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
double arr[] = {111}; 
String str[] = {"dd","aa","bb","cc","ee"}; 
for(int j=0;j<arr.length;j++){ 
li.add(new Double(arr[j])); 
} 
Int locations = Collections. lastIndexOfSubList (list,li); 
System.out.println(“===”+ locations); 
//結(jié)果 3 

9) IndexOfSubList

返回指定源列表中第一次出現(xiàn)指定目標(biāo)列表的起始位置

int count = Collections.indexOfSubList(list,li); 
double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
List li = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
double arr[] = {111}; 
String str[] = {"dd","aa","bb","cc","ee"}; 
for(int j=0;j<arr.length;j++){ 
li.add(new Double(arr[j])); 
} 
Int locations = Collections.indexOfSubList(list,li); 
System.out.println(“===”+ locations); 
//結(jié)果 1 

10) Rotate

根據(jù)指定的距離循環(huán)移動(dòng)指定列表中的元素
Collections.rotate(list,-1);
如果是負(fù)數(shù),則正向移動(dòng),正數(shù)則方向移動(dòng)

double array[] = {112, 111, 23, 456, 231 }; 
List list = new ArrayList(); 
for (int i = 0; i < array.length; i++) { 
list.add(new Double(array[i])); 
} 
Collections.rotate(list,-1); 
for (int i = 0; i <list.size(); i++) { 
System.out.println("list[" + i + "]=" + list.get(i)); 
} 
//結(jié)果:111,23,456,231,112 

以上這篇淺談Java中常用數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)類 Collection和Map就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Mybatis中攔截器的使用場(chǎng)景和技巧分享

    Mybatis中攔截器的使用場(chǎng)景和技巧分享

    Mybatis提供了一些機(jī)制,可以允許我們?cè)谧鰯?shù)據(jù)庫操作的時(shí)候進(jìn)行我們額外的一些程序,當(dāng)然,這看起來并沒有JPA的EntityListener好用,本文小編將給大家詳細(xì)的介紹了Mybatis中攔截器的使用場(chǎng)景和技巧,需要的朋友可以參考下
    2023-10-10
  • Java實(shí)現(xiàn)將PDF轉(zhuǎn)為圖片格式的方法詳解

    Java實(shí)現(xiàn)將PDF轉(zhuǎn)為圖片格式的方法詳解

    PDF文件和圖片文件,這是兩種完全不一樣的格式,可是有的時(shí)候這兩種格式卻是有相互轉(zhuǎn)換的需要,本文將介紹如何通過Java應(yīng)用程序快速高效地將PDF轉(zhuǎn)為圖片格式。一起來看看吧
    2023-03-03
  • Maven依賴沖突的幾種有效解決方法總結(jié)

    Maven依賴沖突的幾種有效解決方法總結(jié)

    在項(xiàng)目開發(fā)中使用Maven管理Jar包時(shí),常常會(huì)遇到Jar包依賴沖突,所以本文就給大家總結(jié)了幾種解決Maven依賴沖突的有效方法,需要的朋友可以參考下
    2023-07-07
  • 詳解Java設(shè)計(jì)模式之單例模式

    詳解Java設(shè)計(jì)模式之單例模式

    單例模式是一種創(chuàng)建型設(shè)計(jì)模式,它的目的是確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)來訪問該實(shí)例,在單例模式中,類自身負(fù)責(zé)創(chuàng)建自己的唯一實(shí)例,并確保在系統(tǒng)中只有一個(gè)實(shí)例存在,本文詳細(xì)介紹了Java設(shè)計(jì)模式中的單例模式,感興趣的同學(xué)可以參考閱讀
    2023-05-05
  • Spring?Security中如何獲取AuthenticationManager對(duì)象

    Spring?Security中如何獲取AuthenticationManager對(duì)象

    有時(shí)需要使用AuthenticationManager(以下簡稱Manager)對(duì)象,可是這個(gè)對(duì)象不是Bean,沒有直接保存在Spring的Bean庫中,那么如何獲取Spring Security中的這個(gè)對(duì)象呢,需要的朋友可以參考下
    2022-11-11
  • Java程序結(jié)構(gòu)與常量變量難點(diǎn)解析

    Java程序結(jié)構(gòu)與常量變量難點(diǎn)解析

    JAVA的基本結(jié)構(gòu)就是順序結(jié)構(gòu),除非特別指明,否則就按照順序一句一句執(zhí)行順序結(jié)構(gòu)是最簡單的算法結(jié)構(gòu),語句與語句之間,框與框之間是按從上到下的順序進(jìn)行的,它是由若干個(gè)依次執(zhí)行的處理步驟組成的,它是任何一個(gè)算法都離不開的一種基本算法結(jié)構(gòu)
    2021-10-10
  • SpringBoot項(xiàng)目部署到服務(wù)器的兩種方式

    SpringBoot項(xiàng)目部署到服務(wù)器的兩種方式

    目前,前后端分離的架構(gòu)已成主流,而使用SpringBoot構(gòu)建Web應(yīng)用是非??焖俚?項(xiàng)目發(fā)布到服務(wù)器上的時(shí)候,只需要打成一個(gè)jar包,然后通過命令 : java -jar jar包名稱即可啟動(dòng)服務(wù)了,本文介紹了SpringBoot項(xiàng)目部署到服務(wù)器的兩種方式,需要的朋友可以參考下
    2024-10-10
  • mybatis簡介與配置_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    mybatis簡介與配置_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了mybatis簡介與配置,介紹了MyBatis+Spring+MySql簡單配置,有興趣的可以了解一下
    2017-09-09
  • Spring源碼之事件監(jiān)聽機(jī)制詳解(@EventListener實(shí)現(xiàn)方式)

    Spring源碼之事件監(jiān)聽機(jī)制詳解(@EventListener實(shí)現(xiàn)方式)

    這篇文章主要介紹了Spring源碼之事件監(jiān)聽機(jī)制(@EventListener實(shí)現(xiàn)方式),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • flatten-maven-plugin使用教程

    flatten-maven-plugin使用教程

    這篇文章主要介紹了flatten-maven-plugin使用,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

南木林县| 玉树县| 九龙县| 沁阳市| 包头市| 崇文区| 平遥县| 平度市| 久治县| 平顶山市| 武冈市| 保康县| 宾阳县| 百色市| 清水河县| 民乐县| 南充市| 嘉鱼县| 阜阳市| 周至县| 昆山市| 汉源县| 永州市| 肥城市| 墨竹工卡县| 许昌市| 囊谦县| 尚志市| 西安市| 昌平区| 嵊泗县| 白银市| 德保县| 彩票| 崇左市| 财经| 常熟市| 沅陵县| 湘潭县| 比如县| 洪泽县|