java-單列集合list與set。

集合定位:存儲數據的容器

與數組的區別:

  • 數組只能存儲同種數據類型數據,集合可以存儲不同類型的數據。

  • 數組的長度一旦創建長度不可變,集合的長度是可變的

  • 數組的操作單一,集合的操作比較豐富(增刪改查)

可以分為單列集合與雙列集合:

單例集合:每個元素(數據)只包含一個值。
collecion--->List集合:ArrayList類LinkedList類添加的元素是有序、可重復、有索引。Set集合:	HashSet: 無序、不重復、無索引;LinkedHashSet: 有序、不重復、無索引。TreeSet:按照大小默認升序排序、不重復、無索引。雙列集合:每個元素包含兩個值(鍵值對)。
Map      -->

1.Collection的常用方法

Collection是單列集合的祖宗,它規定的方法(功能)是全部單列集合都會繼承的。

常用方法如下:

//1.public Object[] toArray(): 把集合轉換為數組
Object[] array = c.toArray();
System.out.println(Arrays.toString(array)); //[java1,java2, java2, java3]//2.如果想把集合轉換為指定類型的數組,可以使用下面的代碼
String[] array1 = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(array1)); //[java1,java2, java2, java3]//3.還可以把一個集合中的元素,添加到另一個集合中
Collection<String> c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String> c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2); //把c2集合中的全部元素,添加到c1集合中去
System.out.println(c1); //[java1, java2, java3, java4]

2.Collection的遍歷方法

2.1 迭代器遍歷集合

原理如下:

  • 當調用iterator()方法獲取迭代器時,當前指向第一個元素

  • hasNext()方法則判斷這個位置是否有元素,如果有則返回true,進入循環

  • 調用next()方法獲取元素,并將當月元素指向下一個位置,

  • 等下次循環時,則獲取下一個元素,依此內推

  • 如果取元素越界,會出現**NoSuchElementException異常。**

Collection<String> c = new ArrayList<>();
c.add("趙敏");
c.add("小昭");
//第一步:先獲取迭代器對象
//解釋:Iterator就是迭代器對象,用于遍歷集合的工具)
Iterator<String> it = c.iterator();//第二步:用于判斷當前位置是否有元素可以獲取
//解釋:hasNext()方法返回true,說明有元素可以獲取;反之沒有
while(it.hasNext()){//第三步:獲取當前位置的元素,然后自動指向下一個元素.String e = it.next();System.out.println(s);
}

2.2 增強for遍歷集合

格式:for(元素的數據類型 變量名:數組或者集合)

增強for不光可以遍歷集合,還可以遍歷數組。

Collection<String> c = new ArrayList<>();
c.add("趙敏");
c.add("小昭");
//1.使用增強for遍歷集合
for(String s: c){System.out.println(s); 
}//2.再嘗試使用增強for遍歷數組
String[] arr = {"迪麗熱巴", "古力娜扎", "稀奇哈哈"};
for(String name: arr){System.out.println(name);
}

2.3 foreach遍歷集合

forEach方法的參數是一個Consumer接口,而Consumer是一個函數式接口,所以可以傳遞Lambda表達式。

Collection<String> c = new ArrayList<>();
c.add("趙敏");
c.add("小昭");
//調用forEach方法
//由于參數是一個Consumer接口,所以可以傳遞匿名內部類
c.forEach(new Consumer<String>{@Overridepublic void accept(String s){System.out.println(s);}
});//也可以使用lambda表達式對匿名內部類進行簡化
c.forEach(s->System.out.println(s)); //[趙敏, 小昭, 素素, 滅絕]

當往集合中存對象時,實際上存儲的是對象的地址值:

3.List系列集合

ArrayList、LinekdList:有序,可重復,有索引。

3.1 List集合的常用方法

3.2 ArrayList底層的原理

ArrayList集合底層是基于數組結構實現的,也就是說當你往集合容器中存儲元素時,底層本質上是往數組中存儲元素。

數組擴容,并不是在原數組上擴容(原數組是不可以擴容的),底層是創建一個新數組,然后把原數組中的元素全部復制到新數組中去。

ArrayList集合適合的應用場景:

  • 適合根據索引查詢數據,或者數據量不是很大時。

  • 不適合在數據量大的同時,又要頻繁的進行增刪操作。

3.3 LinkedList底層原理

LinkedList集合是基于雙向鏈表實現了,所以相對于ArrayList新增了一些可以針對頭尾進行操作的方法,如下圖示所示:

3.4 LinkedList的應用場景

它可以用來設計隊列和棧結構。

//1.創建一個隊列:先進先出、后進后出
LinkedList<String> queue = new LinkedList<>();//入對列queue.addLast("第1號人");
queue.addLast("第2號人");
queue.addLast("第3號人");
queue.addLast("第4號人");
System.out.println(queue);?//出隊列System.out.println(queue.removeFirst());    //第4號人System.out.println(queue.removeFirst());    //第3號人System.out.println(queue.removeFirst());    //第2號人System.out.println(queue.removeFirst());    //第1號人
//1.創建一個棧對象
LinkedList<String> stack = new ArrayList<>();
//壓棧(push) 等價于 addFirst()
stack.push("第1顆子彈");
stack.push("第2顆子彈");
stack.push("第3顆子彈");
stack.push("第4顆子彈");
System.out.println(stack); //[第4顆子彈, 第3顆子彈, 第2顆子彈,第1顆子彈]//彈棧(pop) 等價于 removeFirst()
System.out.println(statck.pop()); //第4顆子彈
System.out.println(statck.pop()); //第3顆子彈
System.out.println(statck.pop()); //第2顆子彈
System.out.println(statck.pop()); //第1顆子彈//彈棧完了,集合中就沒有元素了
System.out.println(list); //[]

4. Set集合

4.1 Set集合的特點

4.2 HashSet底層原理

哈希值就是一個int類型的數值,Java中每個對象都有一個哈希值。

java中的所有對象,都可以調用Object類提供的hashCode方法,返回該對象自己的哈希值。

  • 同一個對象多長調用hashCode()方法返回的哈希值是相同的

  • 不同的對象,它們的哈希值一般不相同,但也有可能相同(哈希碰撞)

數據結構:哈希表(哈希函數+數組+鏈表+紅黑樹)

  1. 創建HashSet初始一個長度為16的數組table,加載因子默認為0.75

  2. 添加元素,首先用元素的hash值和數組長度取余后得到存儲位置,如果位置有數據則調用equals比較兩個值是否相等,相等則不存儲,不相等直接掛在老元素后面,如果鏈表長度超過8且數組長度大于64時,將鏈表轉成紅黑樹,如果紅黑樹節點少于8的時候紅黑樹退化成鏈表。

4.3HashSet去重原理

HashSet存儲元素的原理,依賴于兩個方法:一個是hashCode方法用來確定在底層數組中存儲的位置,另一個是用equals方法判斷新添加的元素是否和集合中已有的元素相同。

要想保證在HashSet集合中沒有重復元素,我們需要重寫元素類的hashCode和equals方法。

4.4 TreeSet集合

reeSet集合的特點是可以對元素進行排序,但是必須指定元素的排序規則。

如何排序?

  • 值為int或Integer等,按照從小到大的順序排序。

  • 字符串,默認按照第一個字符的對應ASCII的值,相同的則比較第二個,直到比出大小。

  • 對象類型:可以讓對象實現Comparable接口,重寫compareTo方法;使用TreeSet的有參構造器 參數Compartor

//第一步:先讓Student類,實現Comparable接口
//注意:Student類的對象是作為TreeSet集合的元素的
public class Student implements Comparable<Student>{private String name;private int age;private double height;//無參數構造方法public Student(){}//全參數構造方法public Student(String name, int age, double height){this.name=name;this.age=age;this.height=height;}//...get、set、toString()方法自己補上..//第二步:重寫compareTo方法//按照年齡進行比較,只需要在方法中讓this.age和o.age相減就可以。/*原理:在往TreeSet集合中添加元素時,add方法底層會調用compareTo方法,根據該方法的結果是正數、負數、還是零,決定元素放在后面、前面還是不存。*/@Overridepublic int compareTo(Student o) {//this:表示將要添加進去的Student對象//o: 表示集合中已有的Student對象return this.age-o.age;}
}
//創建TreeSet集合時,傳遞比較器對象排序
/*
原理:當調用add方法時,底層會先用比較器,根據Comparator的compare方是正數、負數、還是零,決定誰在后,誰在前,誰不存。
*/
//下面代碼中是按照學生的年齡升序排序
Set<Student> students = new TreeSet<>(new Comparator<Student>{@Overridepublic int compare(Student o1, Student o2){//需求:按照學生的身高排序return Double.compare(o1,o2); }
});//創建4個Student對象
Student s1 = new Student("至尊寶",20, 169.6);
Student s2 = new Student("紫霞",23, 169.8);
Student s3 = new Student("蜘蛛精",23, 169.6);
Student s4 = new Student("牛魔王",48, 169.6);//添加Studnet對象到集合
students.add(s1);
students.add(s2);
students.add(s3);
students.add(s4);
System.out.println(students); 

4.5 總結Collection集合

4.6 并發修改異常

在使用迭代器遍歷集合時,可能存在并發修改異常。

下面是出現問題的代碼,問題出在list.remove():

List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("小李子");
list.add("李愛花");
list.add("張全蛋");
list.add("曉李");
list.add("李玉剛");
System.out.println(list); // [王麻子, 小李子, 李愛花, 張全蛋, 曉李, 李玉剛]//需求:找出集合中帶"李"字的姓名,并從集合中刪除
Iterator<String> it = list.iterator();
while(it.hasNext()){String name = it.next();if(name.contains("李")){list.remove(name);}
}
System.out.println(list);

為什么會出現這個異常呢?那是因為迭代器遍歷機制,規定迭代器遍歷集合的同時,不允許集合自己去增刪元素,否則就會出現這個異常

怎么解決這個問題呢?不使用集合的刪除方法,而是使用迭代器的刪除方法,代碼如下:

List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("小李子");
list.add("李愛花");
list.add("張全蛋");
list.add("曉李");
list.add("李玉剛");
System.out.println(list); // [王麻子, 小李子, 李愛花, 張全蛋, 曉李, 李玉剛]//需求:找出集合中帶"李"字的姓名,并從集合中刪除
Iterator<String> it = list.iterator();
while(it.hasNext()){String name = it.next();if(name.contains("李")){//list.remove(name);it.remove(); //當前迭代器指向誰,就刪除誰}
}
System.out.println(list);

l如果能用for循環遍歷時:可以倒著遍歷并刪除;或者從前往后遍歷,但刪除元素后做i --操作。

5. Collection的其他操作

5.1 可變參數

  • 可變參數是一種特殊的形式參數,定義在方法、構造器的形參列表處,它可以讓方法接收多個同類型的實際參數。**

  • 可變參數在方法內部,本質上是一個數組

具體代碼實現如下:

public class ParamTest{public static void main(String[] args){//不傳遞參數,下面的nums長度則為0, 打印元素是[]test();	//傳遞3個參數,下面的nums長度為3,打印元素是[10, 20, 30]test(10,20,30); //傳遞一個數組,下面數組長度為4,打印元素是[10,20,30,40] int[] arr = new int[]{10,20,30,40}test(arr); }public static void test(int...nums){//可變參數在方法內部,本質上是一個數組System.out.println(nums.length);System.out.println(Arrays.toString(nums));System.out.println("----------------");}
}

最后還有一些錯誤寫法,需要讓大家寫代碼時注意一下,不要這么寫哦!!!

  • 一個形參列表中,只能有一個可變參數;否則會報錯**

  • 一個形參列表中如果多個參數,可變參數需要寫在最后;否則會報錯

5.2 Collections工具類

這里的Collections是用來操作Collection的工具類。它提供了一些好用的靜態方法,如下:

演示方法如下:

public class CollectionsTest{public static void main(String[] args){//1.public static <T> boolean addAll(Collection<? super T> c, T...e)List<String> names = new ArrayList<>();Collections.addAll(names, "張三","王五","李四", "張麻子");System.out.println(names);//2.public static void shuffle(List<?> list):對集合打亂順序Collections.shuffle(names);System.out.println(names);//3.public static <T> void short(List<T list): 對List集合排序List<Integer> list = new ArrayList<>();list.add(3);list.add(5);list.add(2);Collections.sort(list);System.out.println(list);}
}

上面我們往集合中存儲的元素要么是Stirng類型,要么是Integer類型,他們本來就有一種自然順序所以可以直接排序。但是如果我們往List集合中存儲Student對象,這個時候想要對List集合進行排序自定義比較規則的。指定排序規則有兩種方式,如下:

排序方式1:讓元素實現Comparable接口,重寫compareTo方法;然后再使用Collections.sort(list集合)對List集合排序

public class Student implements Comparable<Student>{private String name;private int age;private double height;//排序時:底層會自動調用此方法,this和o表示需要比較的兩個對象@Overridepublic int compareTo(Student o){//需求:按照年齡升序排序//如果返回正數:說明左邊對象的年齡>右邊對象的年齡//如果返回負數:說明左邊對象的年齡<右邊對象的年齡,//如果返回0:說明左邊對象的年齡和右邊對象的年齡相同return this.age - o.age;}//...getter、setter、constructor..
}//3.public static <T> void short(List<T list): 對List集合排序
List<Student> students = new ArrayList<>();
students.add(new Student("蜘蛛精",23,169.7));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("紫霞",22,169.8));
students.add(new Student("至尊寶",26,169.5));/*
原理:sort方法底層會遍歷students集合中的每一個元素,采用排序算法,將任意兩個元素兩兩比較;每次比較時,會用一個Student對象調用compareTo方法和另一個Student對象進行比較;根據compareTo方法返回的結果是正數、負數,零來決定誰大,誰小,誰相等,重新排序元素的位置注意:這些都是sort方法底層自動完成的,想要完全理解,必須要懂排序算法才行;
*/
Collections.sort(students);	
System.out.println(students);

?**排序方式2:使用調用sort方法是,傳遞比較器**

/*
原理:sort方法底層會遍歷students集合中的每一個元素,采用排序算法,將任意兩個元素兩兩比較;每次比較,會將比較的兩個元素傳遞給Comparator比較器對象的compare方法的兩個參數o1和o2,根據compare方法的返回結果是正數,負數,或者0來決定誰大,誰小,誰相等,重新排序元素的位置注意:這些都是sort方法底層自動完成的,不需要我們完全理解,想要理解它必須要懂排序算法才行.
*/
Collections.sort(students, new Comparator<Student>(){@Overridepublic int compare(Student o1, Student o2){return o1.getAge()-o2.getAge();}
});	
System.out.println(students);

后續還會更新map集合,上述所涉及圖片均出自b站黑馬程序員java進階課程ppt。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907214.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907214.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907214.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ai之pdf解析工具 PPStructure 還是PaddleOCR

目錄 重點是四 先用 PPStructure 版面分析,分成不同的塊兒,再選用 PaddleOCR、或PPStructure基礎路徑OCR模型配置OCR模型配置GPU配置硬件配置性能配置一、框架選型對比分析1. **PaddleOCR核心能力**2. **PP-Structure核心能力**3. **選型結論**二、錯誤根因分析與修復方案1. …

Android計算機網絡學習總結

TCP vs UDP 核心區別?? ?題目?&#xff1a;TCP為什么稱為可靠傳輸協議&#xff1f;UDP在哪些場景下比TCP更具優勢&#xff1f; ?得分要點?&#xff1a; ?可靠性機制? 三握四揮建立可靠連接確認應答&#xff08;ACK&#xff09; 超時重傳滑動窗口流量控制擁塞控制&…

深入解析Java組合模式:構建靈活樹形結構的藝術

引言&#xff1a;當對象需要樹形組織時 在日常開發中&#xff0c;我們經常需要處理具有層次結構的對象集合。比如&#xff1a; 文件系統中的文件夾與文件GUI界面中的容器與控件企業組織架構中的部門與員工 這類場景中的對象呈現明顯的整體-部分層次結構&#xff0c;如何優雅…

mobaxterm通過ssh登錄docker無圖形界面

1. 流程 下面是使用Mobaxterm通過SSH登錄Docker無圖形界面的步驟&#xff1a; 步驟 操作 1 在本地安裝Mobaxterm 2 配置Mobaxterm連接SSH 3 啟動Docker容器 4 在Mobaxterm中通過SSH連接到Docker容器 2. 操作步驟 步驟1&#xff1a;安裝Mobaxterm 首先&#xff…

【趙渝強老師】HBase的體系架構

HBase是大表&#xff08;BigTable&#xff09;思想的一個具體實現。它是一個列式存儲的NoSQL數據庫&#xff0c;適合執行數據的分析和處理。簡單來說&#xff0c;就是適合執行查詢操作。從體系架構的角度看&#xff0c;HBase是一種主從架構&#xff0c;包含&#xff1a;HBase H…

linux 新增驅動宏config.in配置

?1. 添加配置宏步驟? ?1.1 修改 Kconfig&#xff08;推薦方式&#xff09;? ?定位 Kconfig 文件? 內核各子目錄&#xff08;如 drivers/char/&#xff09;通常包含 Kconfig 文件&#xff0c;用于定義模塊配置選項7。?添加宏定義? 示例&#xff1a;在 drivers/char/Kc…

關于git的使用

下載git 可以去git的官網下載https://git-scm.com/downloads 也可以去找第三方的資源下載&#xff0c;下載后是一個exe應用程序&#xff0c;直接點開一直下一步就可以安裝了 右鍵任意位置顯示這兩個就代表成功&#xff0c;第一個是git官方的圖形化界面&#xff0c;第二個是用…

WPF【11_8】WPF實戰-重構與美化(UI 與視圖模型的聯動,實現INotifyPropertyChanged)

11-13 【重構】INotifyPropertyChanged 與 ObservableCollection 現在我們來完成新建客戶的功能。 當用戶點擊“客戶添加”按鈕以后系統會清空當前所選定的客戶&#xff0c;客戶的詳細信息以及客戶的預約記錄會從 UI 中被清除。然后我們就可以在輸入框中輸入新的客戶信息了&am…

ArkUI:鴻蒙應用響應式與組件化開發指南(一)

文章目錄 引言1.ArkUI核心能力概覽1.1狀態驅動視圖1.2組件化&#xff1a;構建可復用UI 2.狀態管理&#xff1a;從單一組件到全局共享2.1 狀態裝飾器2.2 狀態傳遞模式對比 引言 鴻蒙生態正催生應用開發的新范式。作為面向全場景的分布式操作系統&#xff0c;鴻蒙的北向應用開發…

List優雅分組

一、前言 最近小永哥發現&#xff0c;在開發過程中&#xff0c;經常會遇到需要對list進行分組&#xff0c;就是假如有一個RecordTest對象集合&#xff0c;RecordTest對象都有一個type的屬性&#xff0c;需要將這個集合按type屬性進行分組&#xff0c;轉換為一個以type為key&…

AI與.NET技術實操系列(八):使用Catalyst進行自然語言處理

引言 自然語言處理&#xff08;Natural Language Processing, NLP&#xff09;是人工智能領域中最具活力和潛力的分支之一。從智能客服到機器翻譯&#xff0c;再到語音識別&#xff0c;NLP技術正以其強大的功能改變著我們的生活方式和工作模式。 Catalyst的推出極大降低了NLP…

MySQL 8.0 OCP 1Z0-908 題目解析(13)

題目49 Choose the best answer. t is a non - empty InnoDB table. Examine these statements, which are executed in one session: BEGIN; SELECT * FROM t FOR UPDATE;Which is true? ○ A) mysqlcheck --analyze --all - databases will execute normally on all ta…

Docker 一鍵部署倒計時頁面:Easy Countdown全設備通用

Easy Countdown 介紹 Easy countdown是一個易于設置的倒計時頁面。可以設置為倒計時或計時器。可用于個人生活、工作管理、教育、活動策劃等多個領域。 &#x1f6a2; 項目地址 Github&#xff1a;https://github.com/Yooooomi/easy-countdown &#x1f680;Easy Countdown …

Python訓練打卡Day35

模型可視化與推理 知識點回顧&#xff1a; 三種不同的模型可視化方法&#xff1a;推薦torchinfo打印summary權重分布可視化進度條功能&#xff1a;手動和自動寫法&#xff0c;讓打印結果更加美觀推理的寫法&#xff1a;評估模式 模型結構可視化 理解一個深度學習網絡最重要的2點…

四、生活常識

一、效應定律 效應 1、沉沒成本效應 投入的越多&#xff0c;退出的難度就越大&#xff0c;因為不甘心自己之前的所有付出都付之東流。 2、破窗效應 干凈的環境下&#xff0c;沒有人會第一個丟垃圾&#xff0c;但是當環境變得糟糕&#xff0c;人們就開始無所妒忌的丟垃圾。…

機器學習圣經PRML作者Bishop20年后新作中文版出版!

機器學習圣經PRML作者Bishop20年后新書《深度學習&#xff1a;基礎與概念》出版。作者克里斯托弗M. 畢曉普&#xff08;Christopher M. Bishop&#xff09;微軟公司技術研究員、微軟研究 院 科學智 能 中 心&#xff08;Microsoft Research AI4Science&#xff09;負責人。劍橋…

Python應用嵌套猜數字小游戲

大家好!今天向大家分享的是有關“嵌套”的猜數字小游戲。希望能夠幫助大家理解嵌套。 代碼呈現: # 1. 構建一個隨機的數字變量 import random num random.randint(1, 10)guess_num int(input("輸入你要猜測的數字&#xff1a; "))# 2. 通過if判斷語句進行數字的猜…

黑馬k8s(十四)

1.Service-概述 service&#xff1a;用于四層路由的負載&#xff0c;Ingress七層路由的負載&#xff1b;&#xff0c;先學習service 開啟ipvs 2.Service-資源清單文件介紹 修改每個顯示的內容 ClusterIP類型的Service Endpoints&#xff1a;建立service與pod關聯 親和性測試…

Kotlin 中 Lambda 表達式的語法結構及簡化推導

在 Kotlin 編程中&#xff0c;Lambda 表達式是一項非常實用且強大的功能。今天&#xff0c;我們就來深入探討一下 Lambda 表達式的語法結構&#xff0c;以及它那些令人 “又愛又恨” 的簡化寫法。 一、Lambda 表達式完整語法結構 Lambda 表達式最完整的語法結構定義為{參數名…

Kafka Streams 和 Apache Flink 的無狀態流處理與有狀態流處理

Kafka Streams 和 Apache Flink 與數據庫和數據湖相比的無狀態和有狀態流處理的概念和優勢。 在數據驅動的應用中&#xff0c;流處理的興起改變了我們處理和操作數據的方式。雖然傳統數據庫、數據湖和數據倉庫對于許多基于批處理的用例來說非常有效&#xff0c;但在要求低延遲…