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