摘要:會(huì)死循環(huán),因?yàn)闂?nèi)不會(huì)彈出所以判斷會(huì)一直執(zhí)行。集合用于模擬隊(duì)列這種數(shù)據(jù)結(jié)構(gòu),隊(duì)列通常是指先進(jìn)先出的容器。集合不僅提供了的功能,還提供了雙端隊(duì)列,棧的功能。如果有多個(gè)線程需要訪問集合中的元素,需要考慮使用將幾個(gè)包裝成線程安全集合。
List判斷兩個(gè)對象相等只通過equals方法比較返回true即可。
public class A { @Override public boolean equals(Object arg0) { return true; } } public class SameAListTest { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add(1); list.add(2); list.add(3); //[1, 2, 3] System.out.println(list); list.remove(new A()); //[2, 3] System.out.println(list); list.remove(new A()); //[3] System.out.println(list); } }
從上面程序可以看出,當(dāng)程序試圖刪除一個(gè)A對象,List將會(huì)調(diào)用該A對象的equals方法依次與集合元素進(jìn)行比較,如果該equals方法以某個(gè)集合元素作為參數(shù)時(shí)返回true,List將會(huì)刪除該元素,A重寫了equals方法,該方法總是返回true。
當(dāng)調(diào)用List的set(int index,Object object)方法來改變List集合指定所引處的元素時(shí),指定的索引必須是List集合的有效索引。例如集合長度是4,就不能指定替換索引為4處的元素--也就是說,set(int index,Object object)方法不會(huì)改變List集合的長度。
List還額外提供了一個(gè)listIterator方法,該方法返回一個(gè)ListIterator對象,ListIterator接口繼承了Iterator接口,提供了專門操作List的方法。
public class ListIterators { public static void main(String[] args) { Listlist = new ArrayList<>(); list.add("123"); list.add("231"); list.add("132"); /*正向迭代 * Iterator iterator = list.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }*/ /*//從指定的索引以后的元素進(jìn)行迭代 Lambda迭代 ListIterator listIterator = list.listIterator(1); //231 132 listIterator.forEachRemaining((e) -> System.out.println(e));*/ ListIterator iterator = list.listIterator(); while (iterator.hasNext()) { String next = iterator.next(); System.out.println(next); if ("132".equals(next)) { iterator.add("新添加的"); } } System.out.println("反向迭代 +++++++++++++++++++++"); while (iterator.hasPrevious()) { System.out.println(iterator.previous()); } //[123, 231, 132, 新添加的] System.out.println(list); /* * 123 231 132 反向迭代 +++++++++++++++++++++ 新添加的 132 231 123 [123, 231, 132, 新添加的] */ } }
ListIterator與Iterator相比,ListIterator是反向迭代,Iterator是正向迭代,而且ListIterator還可以通過add方法向List集合中添加元素,Iterator只能刪除元素、
ArrayList和Vector實(shí)現(xiàn)類ArrayList和Vector類都是基于數(shù)組實(shí)現(xiàn)的List類,所以ArrayList和Vector類分裝了一個(gè)動(dòng)態(tài)的,允許再分配的Object[]數(shù)組。ArrayList或Vector對象使用initialCapacity參數(shù)來設(shè)置該數(shù)組的長度,當(dāng)向ArrayList或Vector中添加元素超出了該數(shù)組的長度時(shí),他們的initialCapacity會(huì)自動(dòng)增加。
ArrayList和Vector的區(qū)別是:ArrayList是線程不安全的,當(dāng)多個(gè)線程訪問同一個(gè)ArrayList集合時(shí),如果有超過一個(gè)線程修改了ArrayList集合,則程序必須手動(dòng)保證該集合的同步性,但Vector集合則是線程安全的,無須程序保證該集合的同步性。因此Vector是線程安全的,所以Vector的性能比ArrayList的性能要低;
Vector提供了Stack子類,它用于模擬棧這種數(shù)據(jù)結(jié)構(gòu),棧筒倉是指后進(jìn)先出LIFO的容器,最后push進(jìn)棧的元素,將最先被pop出棧,出入棧的都是Object,
如果程序需要使用棧這種數(shù)據(jù)結(jié)構(gòu),則可以考慮ArrayDeque。
ArrayDeque底層是基于數(shù)組實(shí)現(xiàn)的,因此性能很好。
public class ArrayListAndVector { public static void main(String[] args) { Stack固定長度的Listvector = new Stack<>(); vector.push("1"); vector.push("2"); vector.push("3"); while (!vector.empty()) { System.out.println(vector.pop());// 3 2 1 //System.out.println(vector.peek()); 會(huì)死循環(huán),因?yàn)闂?nèi)不會(huì)彈出所以判斷會(huì)一直執(zhí)行。 } } }
Arrays提供了asList(Object...a)方法,該方法可以把一個(gè)數(shù)組或指定個(gè)數(shù)的對象轉(zhuǎn)化成一個(gè)List集合,這個(gè)List集合時(shí)Arrays的內(nèi)部類ArrayList的實(shí)例。
Array.ArrayList是一個(gè)固定長度的List集合,程序只能遍歷該集合里的元素,不可增加,刪除該集合里的元素。
public class FixedSizeLists { public static void main(String[] args) { ListQueue集合asList = Arrays.asList(new String[]{"1","@","#","$"}); //Exception in thread "main" java.lang.UnsupportedOperationException //System.out.println(asList.add("dsdsd")); } }
Queue用于模擬隊(duì)列這種數(shù)據(jù)結(jié)構(gòu),隊(duì)列通常是指“先進(jìn)先出FIFO”的容器。隊(duì)列的頭部保存在隊(duì)列中存放時(shí)間最長的元素,隊(duì)列的尾部保存在隊(duì)列中存放時(shí)間最短的元素。新元素插入offer到隊(duì)列的尾部,訪問元素poll操作會(huì)返回隊(duì)列頭部的元素。
Queue接口有一個(gè)接口Deque,Deque代表一個(gè)雙端隊(duì)列,雙端隊(duì)列可以同時(shí)從兩端來添加元素,刪除元素,因此Deque的實(shí)現(xiàn)類即可當(dāng)成隊(duì)列使用,也可當(dāng)成棧使用。Java為Deque提供了ArrayDeque和LinkedList兩個(gè)實(shí)現(xiàn)類。
public class QueueTest { public static void main(String[] args) { QueuePriorityQueue實(shí)現(xiàn)類 priority 優(yōu)先的queue = new ArrayDeque<>(); //將指定元素加入此隊(duì)列的尾部,當(dāng)使用有容量限制的隊(duì)列時(shí),此方法通常比add方法更好。 queue.offer(44); queue.add(2); //[44, 2] System.out.println(queue); queue.add(3); //[44, 2, 3] System.out.println(queue); System.out.println(queue.poll());//44 System.out.println(queue);//[2, 3] System.out.println(queue.peek());//2 System.out.println(queue);//[2, 3] queue.remove(); System.out.println(queue);//[3] queue.add(3434); System.out.println(queue);//[3, 3434] //返回隊(duì)列頭部元素,但是不刪除該元素 System.out.println(queue.element());//3 System.out.println(queue);//[3, 3434] System.out.println(queue.remove(3434));//true System.out.println(queue);//[3] } }
PriorityQueue保存隊(duì)列元素的元素并不是按加入隊(duì)列的順序,而是按隊(duì)列元素的大小進(jìn)行重新排序,因此當(dāng)調(diào)用peek方法或者poll方法去除隊(duì)列中的元素時(shí),并不是取出最先進(jìn)入隊(duì)列的元素,而是取出隊(duì)列中的最小的元素。PriorityQueue已經(jīng)違反了隊(duì)列的最基本的原則:先進(jìn)先出
public class PriorityQueues { public static void main(String[] args) { PriorityQueuepriorityQueue = new PriorityQueue<>(); priorityQueue.add(12); priorityQueue.add(-6); priorityQueue.add(-9); priorityQueue.add(1); //[-9, 1, -6, 12] System.out.println(priorityQueue); priorityQueue.poll(); //[-6, 1, 12] System.out.println(priorityQueue); } }
PriorityQueue不允許插入null元素,PriorityQueue可以定制排序和自然排序。
PriorityQueue自然排序的元素必須實(shí)現(xiàn)Comparable接口,而且應(yīng)該是同一個(gè)類的實(shí)例
PriorityQueue不要求隊(duì)列元素實(shí)現(xiàn)Comparable接口。
Deque接口和ArrayDeque實(shí)現(xiàn)類Deque接口是Queue接口的子接口,他代表一個(gè)雙端隊(duì)列。
ArrayList和ArrayDeque兩個(gè)集合類的實(shí)現(xiàn)機(jī)制基本相同,他們的底層都是采用一個(gè)動(dòng)態(tài)的可重新分配的Object[]數(shù)組來保存集合元素,當(dāng)集合元素超出了該數(shù)組的容量時(shí),系統(tǒng)會(huì)在底層重新分配一個(gè)Object[]數(shù)組來存儲(chǔ)集合元素。
把ArrayDeque當(dāng)成棧來使用
public class ArryDeque { public static void main(String[] args) { Dequedeque = new ArrayDeque<>(); deque.push(1); deque.push(2); deque.push(3); deque.push(4); //[4, 3, 2, 1] System.out.println(deque); System.out.println(deque.pop()); // 4 System.out.println(deque);//[3, 2, 1] } } //后入先出
把ArrayDeque當(dāng)成隊(duì)列使用
public class ArryDeque2 { public static void main(String[] args) { Dequedeque = new ArrayDeque<>(); deque.offer(1123); deque.offer(143); deque.offer(-11); System.out.println(deque);//[1123, 143, -11] System.out.println(deque.poll());//1123 System.out.println(deque);//[143, -11] System.out.println(deque.poll());//143 System.out.println(deque);//[-11] } }
ArrayDque不僅可以作為棧使用,也可以作為隊(duì)列使用。
LinkedList實(shí)現(xiàn)類可以根據(jù)索引來隨機(jī)訪問集合中的元素,LinkedList還是實(shí)現(xiàn)了Deque接口,可以被當(dāng)成雙端隊(duì)列來使用,因此既可以被當(dāng)成棧使用,也可以當(dāng)做為隊(duì)列使用。
public class LinkedListTest { public static void main(String[] args) { LinkedListlinkedList = new LinkedList<>(); //將數(shù)組元素加入棧頂 linkedList.push(1); //將數(shù)組元素加入棧底 linkedList.offer(2); //[1, 2] System.out.println(linkedList); //加入棧頂 linkedList.offerFirst(3); //[3, 1, 2] System.out.println(linkedList); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); //3 1 2 } //訪問但不刪除棧底 System.out.println(linkedList.peekLast());//2 //[3, 1, 2] System.out.println(linkedList); //訪問但不刪除棧頂 System.out.println(linkedList.peekFirst());//3 //[3, 1, 2] System.out.println(linkedList); //訪問并刪除棧頂 System.out.println(linkedList.pollFirst());//3 //[1, 2] System.out.println(linkedList); } }
LinkedList和ArrayList和ArrayDeque實(shí)現(xiàn)機(jī)制完全不同
ArrayList,ArrayDeque內(nèi)部以數(shù)組的形式來保存集合中的元素,因此隨機(jī)訪問幾個(gè)元素時(shí)具有較好的性能,而LinkedList內(nèi)部以鏈表的形式來保存集合中的元素,因此隨機(jī)訪問集合元素時(shí)性能較差,但在插入,刪除元素時(shí)性能比較出色,只需要改變指針?biāo)傅牡刂芳纯伞?/p>
對于所有的內(nèi)部基于數(shù)組的集合實(shí)現(xiàn),例如ArrayList和ArrayDeque等,使用隨機(jī)訪問的性能比使用Iterator迭代訪問的性能要好,因?yàn)殡S機(jī)訪問會(huì)被映射成對數(shù)組元素的訪問。
各種線性表的性能分析Java提供的List就是一個(gè)線性表接口,而ArrayList,LinkedList又是線性表的兩種典型實(shí)現(xiàn):基于數(shù)組的線性表和基于鏈的線性表。Queue代表了隊(duì)列,Deque代表了雙端隊(duì)列,既可以作為隊(duì)列使用,又可以當(dāng)做棧使用。
LinkedList集合不僅提供了List的功能,還提供了雙端隊(duì)列,棧的功能。
一般來說,由于數(shù)組以一塊連續(xù)內(nèi)存區(qū)來保存所有的數(shù)組元素,所以數(shù)組在隨機(jī)訪問時(shí)性能最好,所有的內(nèi)部以數(shù)組作為底層實(shí)現(xiàn)的集合在隨機(jī)訪問時(shí)性能都比較好。而內(nèi)部以鏈表作為底層實(shí)現(xiàn)的集合在執(zhí)行插入,刪除操作時(shí)有較好的性能。但總體來說,ArrayList的性能比LinkedList的性能要好,因此大部分時(shí)候都應(yīng)該考慮使用ArrayList。
使用List集合的一些建議
如果需要遍歷List集合,對于ArrayList,Vector集合,應(yīng)該是用隨機(jī)訪問方法get來遍歷集合元素,這樣性能更好。對于LinkedList集合,則應(yīng)該采用迭代器Iterator來遍歷集合元素。
如果需要經(jīng)常執(zhí)行插入,刪除操作來改變含大量數(shù)據(jù)的List集合的大小,則可考慮使用LinkedList集合,使用ArrayList,Vector集合可能需要經(jīng)常分配內(nèi)部數(shù)組的大小,效果可能較差。
如果有多個(gè)線程需要訪問List集合中的元素,需要考慮使用Collections將幾個(gè)包裝成線程安全集合。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69318.html
摘要:第三階段常見對象的學(xué)習(xí)集合框架接口按照集合框架的繼承體系,我們先從中的接口開始學(xué)習(xí)一概述及功能演示概述在中充當(dāng)著一個(gè)什么樣的身份呢有序的也稱為序列實(shí)現(xiàn)這個(gè)接口的用戶以對列表中每個(gè)元素的插入位置進(jìn)行精確地控制。線程不安全,效率高。 第三階段 JAVA常見對象的學(xué)習(xí) 集合框架——List接口 showImg(https://segmentfault.com/img/remote/14600...
摘要:集合的長度的是可變的,可以根據(jù)元素的增加而增長。如果元素個(gè)數(shù)不是固定的推薦用集合。線程安全,效率低。相對查詢慢線程安全的相對增刪慢數(shù)組結(jié)構(gòu)底層數(shù)據(jù)結(jié)構(gòu)是鏈表,查詢慢,增刪快。線程不安全,效率高。 1_對象數(shù)組的概述和使用 A:案例演示 需求:我有5個(gè)學(xué)生,請把這個(gè)5個(gè)學(xué)生的信息存儲(chǔ)到數(shù)組中,并遍歷數(shù)組,獲取得到每一個(gè)學(xué)生信息。 import net.allidea.bean.Stu...
1_(去除ArrayList中重復(fù)字符串元素方式)* A:案例演示 需求:ArrayList去除集合中字符串的重復(fù)值(字符串的內(nèi)容相同) 思路:創(chuàng)建新集合方式 import java.util.ArrayList; import java.util.Iterator; public class ArrayList_1_demo { /* 創(chuàng)建新集合將重復(fù)元素去掉 * 1.明...
摘要:集合代表一個(gè)元素有序可重復(fù)的集合,集合中每個(gè)元素都有其對應(yīng)的順序索引。集合默認(rèn)按元素的添加順序設(shè)置元素的索引。 List集合代表一個(gè)元素有序、可重復(fù)的集合,集合中每個(gè)元素都有其對應(yīng)的順序索引。List集合可以通過索引來訪問指定位置的集合元素。List集合默認(rèn)按元素的添加順序設(shè)置元素的索引。 Java8改進(jìn)的List接口和ListIterator接口 普通方法 List是有序集合,因此L...
摘要:并把最終的隨機(jī)數(shù)輸出到控制臺。方法,在集合中如何存儲(chǔ)元素取決于方法的返回值返回,集合中只有一個(gè)元素。創(chuàng)建集合對象,傳入比較器。 1_HashSet存儲(chǔ)字符串并遍歷 A:Set集合概述及特點(diǎn) 通過API查看即可 B:案例演示 HashSet存儲(chǔ)字符串并遍歷 import java.util.HashSet; public class Demo1_HashSet { p...
摘要:集合框架的基本接口類層次結(jié)構(gòu)其中表示接口,表示實(shí)現(xiàn)類和在實(shí)際開發(fā)中,需要將使用的對象存儲(chǔ)于特定數(shù)據(jù)結(jié)構(gòu)的容器中。實(shí)例是迭代器,擁有兩個(gè)方法方法迭代器用于遍歷集合元素。返回值則是轉(zhuǎn)換后的數(shù)組,該數(shù)組會(huì)保存集合中的所有元素。 Java Collections Framework是Java提供的對集合進(jìn)行定義,操作,和管理的包含一組接口,類的體系結(jié)構(gòu)。 Java集合框架的基本接口/類層次結(jié)構(gòu)...
閱讀 2048·2021-11-08 13:22
閱讀 2509·2021-09-04 16:40
閱讀 1153·2021-09-03 10:29
閱讀 1718·2019-08-30 15:44
閱讀 2125·2019-08-30 11:13
閱讀 2793·2019-08-29 17:07
閱讀 1970·2019-08-29 14:22
閱讀 1252·2019-08-26 14:00