日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java06集合

發(fā)布時(shí)間:2023/11/30 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java06集合 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

13 集合

實(shí)現(xiàn)方法時(shí),不同的數(shù)據(jù)結(jié)構(gòu)會(huì)導(dǎo)致性能有很大差異。

?

13.1 集合接口

Java集合類庫(kù)將接口(interface)與實(shí)現(xiàn)(implementation)分離。

可以使用接口類型存放集合的應(yīng)用,一旦改變了想法,可以輕松額使用另外一種不同的實(shí)現(xiàn)。

List<Integer> l = new ArrayList<>();

若想改為鏈表實(shí)現(xiàn),只需上句為List<Integer> l = new LinkedList<>();

?

Abstract開(kāi)頭的類,如AbstractQueue,是為類庫(kù)實(shí)現(xiàn)者設(shè)計(jì)的。

如果想要實(shí)現(xiàn)自己的隊(duì)列類,會(huì)發(fā)現(xiàn)擴(kuò)展AbstractQueue類要比實(shí)現(xiàn)Queue接口中的方法輕松的多。

?

集合類的基本接口是Collection接口

兩個(gè)基本方法:

public interface Collection<E> {boolean add(E element);Iterator<E> iterator(); }

iterator方法返回一個(gè)實(shí)現(xiàn)了Iterator接口的對(duì)象。

Iterator接口包含三個(gè)方法:

public interface Iterator<E> {E next();boolean hasNext();void remove(); }

Java迭代器被認(rèn)為是在兩個(gè)元素之間的。

當(dāng)調(diào)用next時(shí),迭代器就越過(guò)下一個(gè)元素,并返回剛剛越過(guò)的那個(gè)元素的引用。

remove方法將會(huì)刪除上次調(diào)用next方法時(shí)返回的元素。

如果調(diào)用remove之前沒(méi)有調(diào)用next將是不合法的。

?

由于CollectionIterator都是泛型接口,可以編寫任何集合類型實(shí)用方法。

?

?

?

?

?

?

13.2 具體的集合

Map結(jié)尾的類實(shí)現(xiàn)了Map接口;其他實(shí)現(xiàn)了Collection接口。

ArrayList

順序表

LinkedList

雙向鏈表

ArrayDeque

循環(huán)數(shù)組實(shí)現(xiàn)的雙端隊(duì)列

HashSet

沒(méi)有重復(fù)元素的無(wú)序集合

TreeSet

有序集

EnumSet

包含枚舉類型值的集

LinkedHashSet

可以記住元素插入順序的集

PriorityQueue

允許高效刪除最小元素的集合

HashMap

?

TreeMap

?

EnumMap

鍵值屬于枚舉類型

LinkedHashMap

可以記住K/V的添加次序

WeakHashMap

其值無(wú)用武之地后可以被垃圾回收器回收

IdentityHashMap

==而不是equals比較鍵值的映射表

?

?

LinkedList

interface ListIterator<E> extends Iterator<E> {void add(E element);E previous();boolean hasPrevious(); }

set方法用一個(gè)新元素取代調(diào)用nextprevious方法返回的上一個(gè)元素。

ListIterator<String> iter = list.listIterator();

String oldValue = iter.next(); //returns first element

iter.set(newValue); //sets first element to newValue

?

當(dāng)某個(gè)迭代器修改集合時(shí),另一個(gè)迭代器對(duì)其進(jìn)行遍歷,一定會(huì)出現(xiàn)混亂的狀況。

例如:一個(gè)迭代器指向另一個(gè)迭代器剛剛刪除的元素前面,現(xiàn)在這個(gè)迭代器就是無(wú)效的,并且不應(yīng)該再使用。

鏈表迭代器的設(shè)計(jì)使它能夠檢測(cè)到這種修改。

如果迭代器發(fā)現(xiàn)它的集合被另一個(gè)迭代器修改了,或是被該集合自身的方法修改了,就會(huì)拋出一個(gè)ConcurrentModificationException

例如:

ListIterator<String> iter1 = list.listIterator();

ListIterator<String> iter2 = list.listIterator();

iter1.next();

iter1.remove();

iter2.next(); //throws ConcurrentModificationException

?

鏈表不支持隨機(jī)訪問(wèn),但支持get(int index)

get方法的小優(yōu)化:如果index > size() / 2 就從列表尾端開(kāi)始搜索元素。

for (int i = 0; i < list.size(); ++i)do something with list.get(i);//效率極低。出現(xiàn)此代碼說(shuō)明用錯(cuò)數(shù)據(jù)結(jié)構(gòu)。

nextIndex() ?previousIndex() ?返回索引值

list.listIterator(n)返回一個(gè)迭代器,這個(gè)迭代器指向索引為n的元素前面的位置。

?

?

ArrayList

適用于getset方法。

Vector類的所有方法都是同步的,如果由一個(gè)線程訪問(wèn)Vector,代碼要在同步操作上耗費(fèi)大量的時(shí)間。

ArrayList方法不是同步的。

?

散列集:

散列表(hash table

散列表為每個(gè)對(duì)象計(jì)算一個(gè)整數(shù),稱為散列碼(hash code)。

散列碼是由對(duì)象的實(shí)例域產(chǎn)生的一個(gè)整數(shù)。具有不同數(shù)據(jù)域的對(duì)象將產(chǎn)生不同的散列碼。

散列碼要能夠快速的計(jì)算出來(lái)。

?

Java中,散列表用鏈表數(shù)組實(shí)現(xiàn)。每個(gè)列表被稱為桶(bucket)。

?


散列碼與桶數(shù)的余數(shù)是元素的桶的索引。

?

散列沖突(hash collision

?

將桶數(shù)設(shè)置為預(yù)計(jì)元素個(gè)數(shù)的75%~150%,最好將桶數(shù)設(shè)置為一個(gè)素?cái)?shù),以防鍵的聚集。

標(biāo)準(zhǔn)庫(kù)使用的桶數(shù)是2的冪,默認(rèn)值為16。為表大小提供的任何值都將被自動(dòng)的轉(zhuǎn)換為2的下一個(gè)冪。

?

如果散列表太滿,就需要再散列(rehashed)。

創(chuàng)建一個(gè)雙倍桶數(shù)的表,將所有元素插入到這個(gè)新表中,然后丟棄原來(lái)的表。

裝填因子(load factor)決定何時(shí)對(duì)散列表進(jìn)行再散列。

對(duì)大多數(shù)應(yīng)用程序來(lái)說(shuō),裝填因子為0.75是比較合理的。

?

散列集迭代器依此訪問(wèn)所有的桶,所以訪問(wèn)順序是隨機(jī)的。

HashSet

?


樹(shù)集:

有序集合(sorted collection

紅黑樹(shù)(red-black tree

迭代器以排好序的順序訪問(wèn)每個(gè)元素

?

添加元素到樹(shù)中要比添加到散列表中慢,但是,與將元素添加到數(shù)組或鏈表中相比還是快很多的。

TreeSet

?

對(duì)象的比較:

默認(rèn)情況下,樹(shù)集假定插入的元素實(shí)現(xiàn)了Comparable接口。

public interface Comparable<T> {int compareTo(T other); } a.compareTo(b); //相等返回0;a在前返回負(fù)值;b在前返回正值。

使用Comparable接口定義排序有局限性。

對(duì)于一個(gè)給定的類,只能夠?qū)崿F(xiàn)這個(gè)接口一次。

如果在一個(gè)集合中需要按照部件編號(hào)進(jìn)行排序,在另一個(gè)集合中卻要按照描述信息進(jìn)行排序,該如何?

如果一個(gè)類沒(méi)有實(shí)現(xiàn)Comparable接口,又該如何?

可通過(guò)將Comparator對(duì)象傳遞給TreeSet構(gòu)造器來(lái)告訴樹(shù)集使用不同的比較方法。

pubic interface Comparator<T> {int compare(T a, T b); }

如:

class ItemComparator implements Comparator<Item> {public int compare(Item a, Item b){ return a.getDescription().compareTo(b.getDescription()); } } ItemComparator comp = new ItemComparator(); SortedSet<Item> sortByDescription = new TreeSet<>(comp);
?

比較器是比較方法的持有器,不含數(shù)據(jù),將這種對(duì)象稱為函數(shù)對(duì)象(function object)。

函數(shù)對(duì)象通常動(dòng)態(tài)定義,即定義為匿名內(nèi)部類的實(shí)例。

SortedSet<Item> sortByDescription = new TreeSet<>(new Comparator<Item>() {public int compare(Item a, Item b)return a.getDescription().compareTo(b.getDescription()); }

?

?

隊(duì)列與雙端隊(duì)列:

ArrayDeque

?

優(yōu)先級(jí)隊(duì)列:

priority queue

可以按照任意的順序插入,卻總是按照排序的順序進(jìn)行檢索。

即,無(wú)論何時(shí)調(diào)用remove方法,總會(huì)獲得當(dāng)前優(yōu)先級(jí)隊(duì)列中最小的元素。

優(yōu)先級(jí)隊(duì)列使用的是堆(heap)。

?

映射表:

Map key/value

HashMap ?TreeMap

三種視圖:

Set<K> keySet()

Collection<K> values()

Set<Map.Entry<K, V>> entrySet()

?

弱散列映射表:

WeakHashMap

如果一個(gè)值,對(duì)應(yīng)鍵的唯一引用來(lái)自散列表?xiàng)l目時(shí),這一數(shù)據(jù)結(jié)構(gòu)將與垃圾回收器協(xié)同工作一起刪除鍵/值對(duì)。

?

連接散列集和連接映射表:

LinkedHashSet ?LinkedHashMap 用來(lái)記住插入元素項(xiàng)的順序。

?

鏈接散列映射表將用訪問(wèn)順序而不是插入順序,對(duì)映射表?xiàng)l目進(jìn)行迭代。

?

標(biāo)識(shí)散列映射表:

IdentityHashMap

鍵的散列不是用hashCode函數(shù)來(lái)計(jì)算的,而是用System.identityHashCode方法計(jì)算。

根據(jù)對(duì)象的內(nèi)存地址來(lái)計(jì)算散列碼。

兩個(gè)對(duì)象進(jìn)行比較時(shí),IdentityHashMap使用的是”==”。

在實(shí)現(xiàn)對(duì)象遍歷算法(如對(duì)象序列化)時(shí),這個(gè)類非常有用,可以用來(lái)跟蹤每個(gè)對(duì)象的遍歷狀況。


13.3 集合框架

框架(framework)是一個(gè)類的集,它奠定了創(chuàng)建高級(jí)功能的基礎(chǔ)。

框架包含很多超類,這些超類擁有非常有用的功能、策略和機(jī)制。

框架使用者創(chuàng)建的子類可以擴(kuò)展超類的功能,而不必重新創(chuàng)建這些基本的機(jī)制。

例如Swing就是一種用戶界面的機(jī)制。

Java集合類庫(kù)構(gòu)成了集合類的框架,它為集合的實(shí)現(xiàn)定義了大量的接口和抽象類,并且對(duì)其中的某些機(jī)制給予了描述,例如,迭代協(xié)議。

?

如果想要實(shí)現(xiàn)用于多種集合類型的泛型算法,或者想要增加新的集合類型,必須了解框架。

?

集合有兩個(gè)基本接口:CollectionMap


List是一個(gè)有序集合(ordered collection


標(biāo)記接口RandomAccess,檢測(cè)一個(gè)特定的集合是否支持隨機(jī)檢索。

?

集合接口有大量地方法,這些方法可以通過(guò)更基本的方法加以實(shí)現(xiàn)。

抽象類提供了許多這樣的例行實(shí)現(xiàn)。

如果實(shí)現(xiàn)了自己的集合類,就可能要擴(kuò)展上面某個(gè)類,以便可以選擇例行操作的實(shí)現(xiàn)。

Java類庫(kù)支持下面幾種具體類:

?

?

視圖與包裝器:

keySet方法返回一個(gè)實(shí)現(xiàn)Set接口的類對(duì)象,這個(gè)類的方法對(duì)原映射表進(jìn)行操作。

這種集合稱為視圖。

?

1、輕量級(jí)包裝器

Arrays類的靜態(tài)方法asList將返回一個(gè)包裝了普通Java數(shù)組的List包裝器。

Card[] cardDeck = new Card[52];

List<Card> cardList = Arrays.asList(cardDeck);

改變數(shù)組大小的所有方法都會(huì)拋出一個(gè)UnsupportedOperationException異常。

?

List<String> names = Arrays.asList(“Amy”, “Bob”, “Carl”);

這個(gè)方法調(diào)用Collections.nCopies(n, anObject)方法。

?

2、子范圍視圖

subList方法

List group2 = staff.subList(10, 20); //含首不含尾

可以將任何操作應(yīng)用于子范圍。

?

對(duì)于有序集和映射表,可以使用排序順序建立子范圍。

SortedSet接口聲明了3個(gè)方法:

SortedSet<E> subSet(E from, E to);

SortedSet<E> headSet(E to);

SortedSet<E> tailSet(E from);

?

SortedMap<K, V> subSet(K from, K to);

SortedMap<K, V> headSet(K to);

SortedMap<K, V> tailSet(K from);

?

3、不可修改視圖

Collections.unmodiffiableCollection

Collections.unmodifiableList

Collections.unmodifiableSet

Collections.unmodifiableSortedSet

Collections.unmodifiableMap

Collections.unmodifiableSortedMap

?

每個(gè)方法都定義于一個(gè)接口。

這些視圖對(duì)現(xiàn)有集合增加了一個(gè)運(yùn)行時(shí)的檢查。

如果發(fā)現(xiàn)試圖對(duì)集合進(jìn)行修改,就拋出一個(gè)異常。

?

4、同步視圖

如果由多個(gè)線程訪問(wèn)集合,就必須確保集不會(huì)被意外的破壞。

類庫(kù)的設(shè)計(jì)者使用視圖機(jī)制來(lái)確保常規(guī)集合的線程安全,而不是實(shí)現(xiàn)線程安全的集合類。

Map<String, Employee> map = Collections.synchronizedMap(new HashMap<String, Employee>());

?

5、檢查視圖

List<String> sateStrings = Collections.checkedList(strings, String.class);

視圖的add方法將檢測(cè)插入的對(duì)象是否屬于給定的類。如果不是,則拋出ClassCastException

?

?

批操作:

bulk operation

result.retainAll(a); //保存了交集

result.removeAll(b);

result.addAll(b);

?

集合與數(shù)組之間的轉(zhuǎn)換:

數(shù)組->集合:Arrays.asList包裝器

集合->數(shù)組:toArray()方法

staff.toArray();//返回的是Object數(shù)組,不能強(qiáng)制類型轉(zhuǎn)換;

staff.toArray(new String[0]);//返回的是String數(shù)組;

staff.toArray(new String[staff.size()]); //將元素一次復(fù)制到新數(shù)組中,并返回新數(shù)組

?

13.4 算法

泛型集合接口有一個(gè)很大的優(yōu)點(diǎn),即算法只需要實(shí)現(xiàn)一次。

?

排序:

Collections類中的sort方法。

這個(gè)方法假定元素實(shí)現(xiàn)了Comparable接口。

如果想采用其他方式對(duì)列表進(jìn)行排序,可將Comparator對(duì)象作為第二個(gè)參數(shù)傳遞給sort方法。

降序:Collections.reverseOrder()方法

?

Java直接將所有元素轉(zhuǎn)入一個(gè)數(shù)組,并使用歸并排序的變體對(duì)數(shù)組進(jìn)行排序,然后將排序后的序列復(fù)制回列表。

集合類庫(kù)中使用的歸并排序算法比快速排序要慢,快速排序是通用排序算法的傳統(tǒng)選擇。

歸并排序的優(yōu)點(diǎn),穩(wěn)定,即不需要交換相同的元素。

?

排序的列表必須是可修改的,但不必是可以改變大小的。

·如果列表支持set,則是可修改的;

·如果列表支持addremove方法,則是可改變大小的。

?

混亂:

Collectionsshuffle算法,隨機(jī)的混排列表中元素的順序。

如果沒(méi)有實(shí)現(xiàn)RandomAccess接口,shuffle方法將元素復(fù)制到數(shù)組中,然后打亂數(shù)組元素的順序,最后再將打亂順序后的元素復(fù)制回列表。

?

二分查找:

i = Collections.binarySearch(c, element);

i = Collections.binarySearch(c, element, comparator);

?

二分查找對(duì)順序表有意義,如果對(duì)鏈表采用二分查找,則自動(dòng)變?yōu)轫樞虿檎摇?/p>

?

編寫自己的算法:

如果編寫自己的算法,應(yīng)該盡可能的使用接口,而不要使用具體的實(shí)現(xiàn)。

?

13.5 遺留的集合

Java程序設(shè)計(jì)語(yǔ)言自問(wèn)世以來(lái)就存在的集合:Hashtable ?Properties ?Vector ?Stack ?BitSet

?

Hashtable

HashMap類的作用一樣,擁有相同的接口。

Hashtable的方法也是同步的。

?

枚舉:

使用Enumeration接口對(duì)元素序列進(jìn)行遍歷。

兩個(gè)方法:hasMoreElementsnextElement

靜態(tài)方法Collections.enumeration將產(chǎn)生一個(gè)枚舉對(duì)象,枚舉集合中的元素。

?

屬性映射表:

property map

·鍵和值都是字符串;

·表可以保存到一個(gè)文件中,也可以從文件中加載

·使用一個(gè)默認(rèn)的輔助表。

實(shí)現(xiàn)屬性映射表的類稱為Properties

通常用于程序的特殊配置選項(xiàng)。

?

棧:

stack

?

位集:

BitSet類提供了一個(gè)便于讀取、設(shè)置或清除各個(gè)位的接口。

C++中的bitset功能一樣。

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的Java06集合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。