Java實(shí)用小技能之快速創(chuàng)建List常用幾種方式
引言
集合的概念:
- 在數(shù)學(xué)意義上的概念是: 對個數(shù)據(jù)放置在一起而建立起來的模型,這些數(shù)據(jù)類型可以不同;
- 在軟件中的定義,一堆數(shù)據(jù)放置在一個空間中存儲,將整個存儲空間稱為集合。
本文主要介紹collection接口下的List接口和Set接口,以及迭代器Iterator。
Collection是層次結(jié)構(gòu) 中的根接口,JDK 不提供此接口的任何直接 實(shí)現(xiàn):它提供更具體的子接口(如 Set 和List)實(shí)現(xiàn)。
I Collection接口
1.1 collection的主要子接口和實(shí)現(xiàn)類
1.2 Collection的常用API
II List接口
list接口的實(shí)現(xiàn)類:ArrayList和LinkedList
2.1 ArrayList
原理:變長的數(shù)組 特性:
- 是順序表,方便查找
- 每次擴(kuò)容,集合的長度在原來長度上增加一半。
- 集合默認(rèn)的空間為10.
- ArrayList 是非線程安全的
- 在集合的遍歷過程中,不能使用ArrayList本身的方法刪除和添加元素。
除非通過迭代器自身的 remove 或 add 方法從結(jié)構(gòu)上對列表進(jìn)行修改,否則在任何時間以任何方式對列表進(jìn)行修改,迭代器都會拋出ConcurrentModificationException
ArrayList 的常用API:
2.2 LinkedList
LinkedList的特點(diǎn)
- 底層使用List 接口的鏈接列表實(shí)現(xiàn)。方便刪除和插入。
- 默認(rèn)長度為0.
- LinkedList是非線程安全的。
- 在集合的遍歷過程中,不能使用ArrayList本身的方法刪除和添加元素。
除非通過迭代器自身的 remove 或 add 方法從結(jié)構(gòu)上對列表進(jìn)行修改,否則在任何時間以任何方式對列表進(jìn)行修改,迭代器都會拋出ConcurrentModificationException
2.3 補(bǔ)充:List的實(shí)現(xiàn)類 Vector
Vector 類可以實(shí)現(xiàn)可增長的對象數(shù)組,Vector的特性如下:
- 順序表,方便查找
- 每次擴(kuò)容在原長度上增加一倍。
- 默認(rèn)大小為10
- Vector是線程安全。
2.4 快速創(chuàng)建List常用幾種方式
- 常規(guī)操作:
new ArrayList<>()
創(chuàng)建
List<Integer> list = new ArrayList<>(); list.add(1); list.add(2);
- Arrays工具類創(chuàng)建
構(gòu)造靜態(tài)不變的 List:
List<String> excludeFields = Arrays.asList("secretKey","privateKey","publicKey"); //這種方式構(gòu)造的 List 是固定長度的,如果調(diào)用 add 方法增加新的元素時會報異常 java.lang.UnsupportedOperationException。
如果想要改變可以通過 ArrayLis t進(jìn)行包裝成動態(tài)。
List<Integer> list = Arrays.asList(1, 2, 3); list = new ArrayList<>(list); list.add(4);
- Stream創(chuàng)建
List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());
- 匿名內(nèi)部類創(chuàng)建
List<Integer> list= new ArrayList() {{ add(1); add(2); add(3); }};
- Hutool工具類創(chuàng)建
List<Integer> list = CollectionUtil.newArrayList(1, 2, 3);
- guava工具類創(chuàng)建
import com.google.common.collect.Lists; List<Integer> list = Lists.newArrayList(1, 2, 3);
- JDK9 引入的Lists創(chuàng)建
List<Integer> list = Lists.newArrayList(1, 2, 3);
- JDK9引入 List.of (不可變)
List<Integer> list = List.of(1,2,3);
III 迭代器
3.1 迭代器的特點(diǎn)
- Iterator接口,本身是一種快速遍歷集合的算法。
- 集合可以調(diào)用iterator方法獲取迭代器。
- 迭代器是一個帶有游標(biāo)的線性表,用來記錄集合的元素地址。
3.2 迭代器與集合的關(guān)系
關(guān)系草圖
相關(guān)代碼片
public class IteratorDemo{ public static void main(String[] args){ List l=new ArrayList(); l.add("abc"); l.add("123"); l.add("中國"); Iterator it=L.iterator(); } }
3.3 Iterator的常用API
IV Set接口
特點(diǎn)類似于數(shù)學(xué)集合,無順序,不可重復(fù),與List的特點(diǎn)相反,他只能有一個null值。 在這里講講他的實(shí)現(xiàn)類:HashSet,和TreeSet。
4.1 HashSet
基于哈希表的 Map 接口的實(shí)現(xiàn),特點(diǎn)如下:
- 采用hash算法的Set,相當(dāng)于hashMap的Key。
- 默認(rèn)的容量為16,加載因子75%。
- HashSet非線程安全。
- 此實(shí)現(xiàn)不是同步的。
- 在集合的遍歷過程中,不能使用ArrayList本身的方法刪除和添加元素。
除非通過迭代器自身的 remove 或 add 方法從結(jié)構(gòu)上對列表進(jìn)行修改,否則在任何時間以任何方式對列表進(jìn)行修改,迭代器都會拋出ConcurrentModificationException
4.2 TreeSet
特點(diǎn):
- 默認(rèn)的空間為0
- 采用二叉樹算法實(shí)現(xiàn)的
- 原理為TreeMap的Key
- 在集合的遍歷過程中,不能使用ArrayList本身的方法刪除和添加元素。
除非通過迭代器自身的 remove 或 add 方法從結(jié)構(gòu)上對列表進(jìn)行修改,否則在任何時間以任何方式對列表進(jìn)行修改,迭代器都會拋出ConcurrentModificationException
- 按照自然排序存放元素
V 面試題
5.1 說出ArrayList和LinkedList的區(qū)別
- ArrayList和LinkedList都實(shí)現(xiàn)了List接口,但ArrayList采用動態(tài)數(shù)組的方式,而LinkedList采用雙向鏈表的方式。 對于通過下標(biāo)來訪問元素時ArrayList效率較高而對于刪除和插入操作
LinkedList
效率較高。 - LinkedList還實(shí)現(xiàn)了Queue和Deque接口,可以用作隊列或棧,例如:
package com.csuinfosoft.grammer.ListDemo; import java.util.Deque; import java.util.LinkedList; import java.util.Queue; /** * * @author iOS逆向 * @date 上午8:32:37 * ArrayList和LinedList都實(shí)現(xiàn)了List接口,但LinkedList還實(shí)現(xiàn)了Queue和Deque接口, * 可以用作隊列和棧。(其中在jdk6.0,LinkedList才實(shí)現(xiàn)Deque接口) */ public class LinkedListOfqueue { public static void main(String[] args) { Queue queue=new LinkedList(); //入隊 queue.offer("A");// boolean offer(E o) 如果可能,將指定的元素插入此隊列 queue.offer("B"); queue.offer("C"); //出隊 System.out.println(queue.poll());// E poll() 檢索并移除此隊列的頭,如果此隊列為空,則返回 null。 System.out.println(queue.poll()); Deque stack=new LinkedList(); //入棧 stack.push("A");//void push(E e)將一個元素推入此雙端隊列所表示的堆棧(換句話說,此雙端隊列的頭部),如果可以直接這樣做而不違反容量限制的話; //如果成功,則返回 true,如果當(dāng)前沒有可用空間,則拋出 IllegalStateException。 stack.push("B"); stack.push("C"); //出棧 System.out.println(stack.pop());// E pop() 從此雙端隊列所表示的堆棧中彈出一個元素。 System.out.println(stack.pop()); } } queue=new LinkedList(); //入隊 queue.offer("A");// boolean offer(E o) 如果可能,將指定的元素插入此隊列 queue.offer("B"); queue.offer("C"); //出隊 System.out.println(queue.poll());// E poll() 檢索并移除此隊列的頭,如果此隊列為空,則返回 null。 System.out.println(queue.poll()); Deque stack=new LinkedList(); //入棧 stack.push("A");//void push(E e)將一個元素推入此雙端隊列所表示的堆棧(換句話說,此雙端隊列的頭部),如果可以直接這樣做而不違反容量限制的話; //如果成功,則返回 true,如果當(dāng)前沒有可用空間,則拋出 IllegalStateException。 stack.push("B"); stack.push("C"); //出棧 System.out.println(stack.pop());// E pop() 從此雙端隊列所表示的堆棧中彈出一個元素。 System.out.println(stack.pop()); } }
5.2 使用內(nèi)部類來解決接口方法被替換的問題
解決方案:回調(diào)模式
package zx.callback; public class Test { /** * @param args * @return void */ public static void main(String[] args) { //實(shí)例化一個講師 TeacherPro2 pro=new TeacherPro2("kunnan"); //作為程序員工作 pro.work(); //調(diào)用繼承的方法 //作為老師工作 pro.asTeacher().work();//使用內(nèi)部類來解決接口方法被替換的問題 //pro.asTeacher()由pro創(chuàng)建,pro.asTeacher()的work()方法調(diào)用了pro的teach方法。體現(xiàn)了回調(diào)功能。 } }
- Teacher接口
package zx.callback; public interface Teacher { void work();//定義工作 }
- Programmer類
package zx.callback; /** * 程序員 * * @author zhang_kn * */ public class Programmer { private String name; public Programmer() { } public Programmer(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void work() { System.out.println("天天寫代碼,天天需求被改。。ios。"); } }
- TeacherPro2類
pro.asTeacher()由pro創(chuàng)建,pro.asTeacher()的work()方法調(diào)用了pro的teach方法。體現(xiàn)了回調(diào)功能。
package zx.callback; public class TeacherPro2 extends Programmer { // 定義一個方法作為教師的職責(zé)授課,使用private修飾 private void teach() { System.out.println("講課。。。"); } // 提供內(nèi)部類,使用private修飾 private class Coust implements Teacher { public void work() {//避免與TeacherPro2 繼承的work方法重復(fù) teach();//執(zhí)行教師的職責(zé)。使用TeacherPro2 的資源teach。體現(xiàn)了回調(diào)模式。 } } public Teacher asTeacher() {//提供給外界獲取包含老師功能的實(shí)現(xiàn)類的接口 return new Coust(); } public TeacherPro2() { super(); } public TeacherPro2(String name) { super(name); } }
總結(jié)
到此這篇關(guān)于Java實(shí)用小技能之快速創(chuàng)建List常用幾種方式的文章就介紹到這了,更多相關(guān)Java快速創(chuàng)建List方式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot的LogbackLoggingSystem配置加載流程解析
這篇文章主要介紹了springboot的LogbackLoggingSystem配置加載流程源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11SpringBoot整合Dubbo框架,實(shí)現(xiàn)RPC服務(wù)遠(yuǎn)程調(diào)用
Dubbo是一款高性能、輕量級的開源Java RPC框架,它提供了三大核心能力:面向接口的遠(yuǎn)程方法調(diào)用,智能容錯和負(fù)載均衡,以及服務(wù)自動注冊和發(fā)現(xiàn)。今天就來看下SpringBoot整合Dubbo框架的步驟2021-06-06Java零基礎(chǔ)教程之Windows下安裝 JDK的方法圖解
這篇文章主要介紹了Java零基礎(chǔ)教程之Windows下安裝 JDK的方法圖解,本文介紹的非常詳細(xì),具有參考借鑒價值,需要的朋友可以參考下2016-09-09BufferedInputStream(緩沖輸入流)詳解_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要為大家詳細(xì)介紹了BufferedInputStream緩沖輸入流的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05idea快速實(shí)現(xiàn)將SpringBoot項目打包Docker鏡像并部署
本文主要介紹了idea快速實(shí)現(xiàn)將SpringBoot項目打包Docker鏡像并部署,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04java substring(a)與substring(a,b)的使用說明
這篇文章主要介紹了java substring(a)與substring(a,b)的使用說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10springboot整合企微webhook機(jī)器人發(fā)送消息提醒
這篇文章主要為大家介紹了springboot整合企微webhook機(jī)器人發(fā)送消息提醒,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12SpringBoot使用Redisson實(shí)現(xiàn)延遲執(zhí)行的完整示例
這篇文章主要介紹了SpringBoot使用Redisson實(shí)現(xiàn)延遲執(zhí)行的完整示例,文中通過代碼示例講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-06-06學(xué)習(xí)Java的Date、Calendar日期操作
Java開發(fā)過程中避免不了日期相關(guān)操作,這篇文章總結(jié)了一些Date、Calendar的常用方法,需要的朋友可以參考下2015-07-07