目錄
一.Collection
二.List集合
三.ArrayList集合
四.LinkedList集合
五.Set集合? ? ? ???????
六.hashSet集合
七.LinkedHashSet集合
八.TreeSet集合
九.集合工具類Collections
集合體系概述
????????單列集合:Collection代表單列集合,每個元素(數(shù)據(jù))只包含一個值。
????????雙列集合:Map代表雙列集合,每個元素包含兩個值(鍵值對)。
單列集合:
????????List系列集合:添加的元素是有序、可重復、有索引
????????????????ArrayList:有序、可重復、有索引
????????????????LinekdList:有序、可重復、有索引
????????Set系列集合:添加的元素是無序、不重復、無索引
? ? ? ?????????HashSet:無序、不重復、無索引
???????????????LinkedHashSet:有序、不重復、無索引
???????????????TreeSet:按照大小默認升序排序、不重復、無索引
一.Collection
為什么要先學Collection的常用方法?
????????Collection是單列集合的祖宗,它規(guī)定的方法(功能)是全部單列集合都會繼承的。
Collection的常用方法:
代碼展示:
package com.itheima.day06.teacher.g_collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
/**
* Collection常用方法
*/
public class CollectionDemo {
public static void main(String[] args) {
/*
Collection 是 ArrayList祖宗
*/
// Collection<String> con = new ArrayList<>();//多態(tài)
// ArrayList<String> list = new ArrayList<>();//本態(tài)
//采用多態(tài)?為什么呢? 多態(tài)特點 多態(tài)下只能調(diào)用 父中定義的功能,不會調(diào)用子類特有的。
// 我們要研究是 共性的功能 使用多態(tài)
Collection<String> con = new ArrayList<>();//多態(tài)
// add()
con.add("name1");
con.add("name2");
con.add("name3");
con.add("name4");
System.out.println(con);
//size() 獲取集合長度 元素個數(shù)
System.out.println("集合中有"+con.size()+"個元素");
// boolean contains(元素) 判斷集合中是否包含指定元素
System.out.println("是否包含張三 "+con.contains("張三"));//false
System.out.println("是否包含趙四 "+con.contains("趙四"));//true
//boolean remove(元素) 刪除指定元素 返回 是否刪除成功
System.out.println("刪除一下:王老七 "+con.remove("王老七"));
System.out.println(con);
//情況集合方法 void clear()
con.clear();
System.out.println("清空集合之后:"+con);
// isEmpty() 判斷集合是否為空
System.out.println("con當前是空的嗎?"+con.isEmpty());
// 重寫添加數(shù)據(jù)
con.add("謝大腳");
con.add("王小蒙");
con.add("香秀");
con.add("王云");
// Object[] toArray() 變成數(shù)組
Object[] array = con.toArray();
System.out.println(Arrays.toString(array));
//擴展一個
Collection<String> c1 = new ArrayList<>();//多態(tài)
// add()
c1.add("name1");
c1.add("name2");
c1.add("name3");
c1.add("name4");
Collection<String> c2 = new ArrayList<>();//多態(tài)
// add()
c2.add("name1");
c2.add("name2");
c2.add("name3");
c2.add("name4");
c1.addAll(c2);//c2集合內(nèi)容 批量添加到c1中
System.out.println(c1);
}
}
Collection的遍歷方式:
1.迭代器:
????????迭代器是用來遍歷集合的專用方式(數(shù)組沒有迭代器),在Java中迭代器的代表是Iterator。
????????Collection集合獲取迭代器的方法??Iterator<E> iterator()?返回集合中的迭代器對象,該迭代器對象默認指向當前集合的第一個元素
????????Iterator迭代器中的常用方法:
????????boolean hasNext():詢問當前位置是否有元素存在,存在返回true ,不存在返回false
????????E next():獲取當前位置的元素,并同時將迭代器對象指向下一個元素處。
2.增強for循環(huán):
? ? ? ? 格式:for (元素的數(shù)據(jù)類型 變量名 : 數(shù)組或者集合) { }
????????增強for可以用來遍歷集合或者數(shù)組。
????????增強for遍歷集合,本質(zhì)就是迭代器遍歷集合的簡化寫法。
3.lambda表達式
????????得益于JDK 8開始的新技術(shù)Lambda表達式,出現(xiàn)了一種更簡單、更直接遍歷集合的方式-Lambda表達式。
????????需要使用Collection的如下方法來完成:default void forEach(Consumer<? super T> action)
????????lists.forEach(s -> {System.out.println(s); });
package com.itheima.day06.teacher.g_collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo2 {
public static void main(String[] args) {
/*
Collection 是 ArrayList祖宗
*/
// Collection<String> con = new ArrayList<>();//多態(tài)
// ArrayList<String> list = new ArrayList<>();//本態(tài)
//采用多態(tài)?為什么呢? 多態(tài)特點 多態(tài)下只能調(diào)用 父中定義的功能,不會調(diào)用子類特有的。
// 我們要研究是 共性的功能 使用多態(tài)
Collection<String> con = new ArrayList<>();//多態(tài)
// add()
con.add("name1");
con.add("name2");
con.add("name3");
con.add("name4");
System.out.println(con);
//size() 獲取集合長度 元素個數(shù)
// for (int i = 0; i < con.size(); i++) {
// String s = con.get(i);//Conllection 認為無索引
// }
// Collection集合的遍歷 需要借助一個工具 來完成遍歷(迭代)
// 迭代器 Interator
// 每一個集合對象 都有自己的 迭代器。
// 呼叫迭代器 獲取迭代器
Iterator<String> it = con.iterator();
// iterator 可以幫助集合完成 元素的獲取
// 迭代器指向第一個元素
while(it.hasNext()){//詢問 當前位置是否有元素 有true false
//再去獲取
String e = it.next();
System.out.println(e);
}
}
}
-------------
package com.itheima.day06.teacher.g_collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionDemo3 {
public static void main(String[] args) {
/*
Collection 是 ArrayList祖宗
*/
// Collection<String> con = new ArrayList<>();//多態(tài)
// ArrayList<String> list = new ArrayList<>();//本態(tài)
//采用多態(tài)?為什么呢? 多態(tài)特點 多態(tài)下只能調(diào)用 父中定義的功能,不會調(diào)用子類特有的。
// 我們要研究是 共性的功能 使用多態(tài)
Collection<String> con = new ArrayList<>();//多態(tài)
// add()
con.add("name1");
con.add("name2");
con.add("name3");
con.add("name4");
System.out.println(con);
//因為開發(fā)中 大量場景都要使用到 集合 都要去完成遍歷 所以jdk 升級的時候 做了一個很高明的操作 就是簡化迭代器的使用
/*
增強for - --單列集合 數(shù)組
for(數(shù)據(jù)類型 變量名 :被遍歷的集合/數(shù)組){}
*/
// for(String s:con){
// System.out.println(s);
// }
//集合.for
for (String s : con) {
System.out.println(s);
}
//增強for 只適合于獲取數(shù)據(jù) 不適合與修改
}
}
----------
package com.itheima.day06.teacher.g_collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.Consumer;
public class CollectionDemo4 {
public static void main(String[] args) {
/*
Collection 是 ArrayList祖宗
*/
// Collection<String> con = new ArrayList<>();//多態(tài)
// ArrayList<String> list = new ArrayList<>();//本態(tài)
//采用多態(tài)?為什么呢? 多態(tài)特點 多態(tài)下只能調(diào)用 父中定義的功能,不會調(diào)用子類特有的。
// 我們要研究是 共性的功能 使用多態(tài)
Collection<String> con = new ArrayList<>();//多態(tài)
// add()
con.add("name1");
con.add("name2");
con.add("name3");
con.add("name4");
System.out.println(con);
/*
jdk8提供的 foreach
*/
con.forEach(new Consumer<String>() {
@Override
public void accept(String s) {//s 接收每次得到的數(shù)據(jù)
System.out.println(s);
}
});
System.out.println("=================");
con.forEach(s -> System.out.println(s));
con.forEach(System.out::println);
}
}
二.List集合
? ? ? ?1.List集合因為支持索引,所以多了很多與索引相關(guān)的方法
????????特有方法:
????????
2.遍歷方式:
? ? ? ? 1.for循環(huán)(因為List集合有索引)
? ? ? ? 2.迭代器
? ? ? ? 3.增強for循環(huán)
? ? ? ? 4.Lambda表達式
package com.itheima.day07.teacher.list01;
import java.util.ArrayList;
import java.util.List;
public class ListDemo {
/*
Collection 單列集合頂層接口
里面定義關(guān)于元素的 一些 獲取添加刪除的通用方法
--- List 子接口 有序集合
特點:
有序 可以重復 有索引
里面 有寫特有和索引相關(guān)方法
增 void add(int index,E e) 往集合指定位置添加元素
刪 E remove(int index) 根據(jù)指定索引進行刪除 返回被刪除元素
改 E set(int index,E e) 根據(jù)索引進行元素替換,返回被替換的元素
查 E get(int index) 根據(jù)索引獲取元素
*/
public static void main(String[] args) {
// 這是多態(tài)寫法 因為在多態(tài)下只能使用List 接口定義的方法
List<String> list = new ArrayList<>();
//添加元素
list.add("name1");
list.add("name2");
list.add("name3");
list.add("name4");
System.out.println(list);
//有序--存取順序一致。且有索引
// 索引為3的位置添加一個 真玲
list.add(3,"真玲");
System.out.println(list);
// 刪除
// 刪除索引為4的元素
String remove = list.remove(4);
System.out.println("刪除索引為4的元素:"+remove);
System.out.println("刪除后的集合:"+list);
// System.out.println(list.remove(4)); 報錯 索引越界
//修改 索引為2的 改為狗蛋
System.out.println(list.set(2,"狗蛋"));
System.out.println("修改后的集合:"+list);
// 獲取 索引為1的元素
System.out.println(list.get(1));
}
}
-----------
package com.itheima.day07.teacher.list01;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListDemo02 {
public static void main(String[] args) {
/*
完成集合的遍歷
遍歷方式 四種
*/
List<String> list = new ArrayList<>();
list.add("name1");
list.add("name2");
list.add("name3");
list.add("name4");
//普通for循環(huán) list集合.fori
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("===============");
//迭代器 iterator()
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("===============");
//增強for list集合.for
for (String s : list) {
System.out.println(s);
}
// lambda 集合.forEach
list.forEach(s -> System.out.println(s));
System.out.println("===============");
list.forEach(System.out::println);
}
}
三.ArrayList集合
? ? ? ? 1.ArrayList集合底層是基于數(shù)組實現(xiàn)的
? ? ? ? 2.數(shù)組的特點:查詢快,增刪慢(數(shù)組長度固定,增刪需要新數(shù)組效率低)
? ? ? ? 3.ArrayList集合對象的創(chuàng)建和擴容過程
????????????????1、利用無參構(gòu)造器創(chuàng)建的集合,會在底層創(chuàng)建一個默認長度為0的數(shù)組
????????????????2、添加第一個元素時,底層會創(chuàng)建一個新的長度為10的數(shù)組
? ? ? ? ? ? ? ? 3、存滿時,會擴容1.5倍??
????????????????4、如果一次添加多個元素,1.5倍還放不下,則新創(chuàng)建數(shù)組的長度以實際為準
? ? ? ? 4.ArrayList集合適合什么業(yè)務(wù)場景?不適合什么業(yè)務(wù)場景?????????
????????????????適合根據(jù)索引查詢數(shù)據(jù)的場景或者數(shù)據(jù)量不是很大的場景
????????????????不適合數(shù)據(jù)量很大時又要頻繁地進行增刪操作的場景
? ? ? ? 因為比較常用我單獨寫了一篇
四.LinkedList集合
? ? ? ? 1.LinkedList集合底層是基于雙鏈表實現(xiàn)的
? ? ? ? 2.鏈表中的結(jié)點是獨立的對象,在內(nèi)存中是不連續(xù)的,每個結(jié)點包含數(shù)據(jù)值和下一個結(jié)點的地址。
? ? ? ? 3.鏈表的特點:查詢慢,都要從頭開始找,增刪快
? ? ? ? 4.雙鏈表的特點:
????????????????每個節(jié)點包含數(shù)據(jù)值和上一個節(jié)點的地址以及下一個節(jié)點的地址
????????????????查詢慢,增刪相對較快,但對首尾元素進行增刪改查的速度是極快的
????????5.LinkedList新增了:很多首尾操作的特有方法。
????????????????
????????6.LinkedList集合適合需要頻繁操作首尾元素的場景,比如棧和隊列
????????
package com.itheima.day07.teacher.list02;
import java.util.LinkedList;
public class LikendListDemo01 {
public static void main(String[] args) {
/*
用LinkedList模擬 小火車過山洞...模擬 隊列結(jié)構(gòu)
隊列結(jié)構(gòu)
先進先出 FIFO
*/
LinkedList<String> list = new LinkedList<>();
//入隊 進山洞
list.addLast("火車頭");
list.addLast("第一節(jié)車廂");
list.addLast("第二節(jié)車廂");
list.addLast("第三節(jié)車廂");
list.addLast("火車尾");
//出山洞
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
System.out.println(list.removeFirst());
}
}
------------
package com.itheima.day07.teacher.list02;
import java.util.LinkedList;
public class LinkedListDemo02 {
public static void main(String[] args) {
/*
模擬彈夾 發(fā)射子彈
棧結(jié)構(gòu)
特點 先進后出 FILO
*/
LinkedList<String> danJia = new LinkedList<>();
// 壓 子彈
danJia.addFirst("第一顆子彈");//每次都在最上面
danJia.addFirst("第二顆子彈");//每次都在最上面
danJia.addFirst("第三顆子彈");//每次都在最上面
danJia.addFirst("第四顆子彈");//每次都在最上面
// 射子彈
System.out.println(danJia.removeFirst());//每次射最上面的
System.out.println(danJia.removeFirst());
System.out.println(danJia.removeFirst());
System.out.println(danJia.removeFirst());
}
}
????????
五.Set集合? ? ? ???????
整體特點:? 無序 ,存取順序不保證一致; 不重復; 無索引;
HashSet:??無序、不重復、無索引
LinkedHashSet:有序、不重復、無索引
TreeSet:可排序、不重復、無索引
六.hashSet集合
1.哈希值:
? ? ? ? 1.就是一個int類型的數(shù)值,Java中每個對象都有一個哈希值
? ? ? ? 2.Java中的所有對象,都可以調(diào)用Obejct類提供的hashCode方法,返回該對象自己的哈希值
2.對象哈希值的特點:?
????????同一個對象多次調(diào)用hashCode()方法返回的哈希值是相同的。
????????不同的對象,它們的哈希值一般不相同,但也有可能會相同(哈希碰撞)。?
3.HashSet底層基于哈希表實現(xiàn)
????????JDK8之前,哈希表 = 數(shù)組+鏈表:
? ? ? ? ? ? ? ? 1.創(chuàng)建一個默認長度16的數(shù)組,默認加載因子為0.75,數(shù)組名table
? ? ? ? ? ? ? ? 2.使用元素的哈希值對數(shù)組的長度求余計算出應(yīng)存入的位置
? ? ? ? ? ? ? ? 3.判斷當前位置是否為null,如果是null直接存入
? ? ? ? ? ? ? ? 4.如果不為null,表示有元素,則調(diào)用equals方法比較
????????JDK8開始,哈希表 = 數(shù)組+鏈表+紅黑樹(一種平衡的二叉樹)
????????????????JDK8開始,當鏈表長度超過8,且數(shù)組長度>=64時,自動將鏈表轉(zhuǎn)成紅黑樹
????????????????JDK8開始后,哈希表中引入了紅黑樹后,進一步提高了操作數(shù)據(jù)的性能。
????????哈希表是一種增刪改查數(shù)據(jù)性能都較好的結(jié)構(gòu)。
4.數(shù)據(jù)結(jié)構(gòu):樹
????????二叉查找樹:規(guī)則:小的往左存,大的往右存,一樣的不存
????????可能存在的問題:當數(shù)據(jù)已經(jīng)是排好序的,導致查詢的性能與單鏈表一樣,查詢速度變慢!
????????平衡二叉樹:在滿足二叉查找樹的大小規(guī)則下,讓樹盡可能矮小,以此提高查數(shù)據(jù)的性能。
????????紅黑樹:是一種可以自平衡的二叉樹,紅黑樹是一種增刪改查數(shù)據(jù)性能相對都較好的結(jié)構(gòu)
5.如何讓HashSet集合能夠?qū)崿F(xiàn)對內(nèi)容一樣的兩個不同對象也能去重復?
????????重寫hashCode()和equals()方法
package com.itheima.day07.teacher.set02;
import java.util.Objects;
/**
* 學術(shù)類
*/
public class 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;
}
/**
* 獲取
* @return name
*/
public String getName() {
return name;
}
/**
* 設(shè)置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 獲取
* @return age
*/
public int getAge() {
return age;
}
/**
* 設(shè)置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 獲取
* @return height
*/
public double getHeight() {
return height;
}
/**
* 設(shè)置
* @param height
*/
public void setHeight(double height) {
this.height = height;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + ", height = " + height + "}";
}
//利用idea快捷鍵 hashCode equals
/*
比較兩個對象的內(nèi)容
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age && Double.compare(student.height, height) == 0 && Objects.equals(name, student.name);
}
/*
根據(jù)屬性算哈希值 盡量不一樣的屬性 值不同 減少哈希碰撞
*/
@Override
public int hashCode() {
return Objects.hash(name, age, height);
}
}
------------
package com.itheima.day07.teacher.set02;
import java.util.HashSet;
public class HashSetDemo {
public static void main(String[] args) {
/*
創(chuàng)建一個學生集合 用來存儲不同 學生對象
*/
HashSet<Student> set = new HashSet<>();
//創(chuàng)建學生對象
Student stu1 = new Student("小磊",18,1.88);
Student stu2 = new Student("小鑫",28,1.38);
Student stu3 = new Student("小哲",22,1.78);
Student stu4 = new Student("小鑫",28,1.38);
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu2);
set.add(stu4);//我們沒有重寫 hashCode equals的時候可以存儲進去的,
// 原因是 存的時候先調(diào)用 hashCode方法(Object--根地址有一定關(guān)系) 哈希code不一樣.
// 即使哈希一樣,也能存!!沒有重寫equals 比較的是地址值 不是一個元素。
/*
在開發(fā)過程中
是地址值不一樣就是不同對象嗎?
其實不盡然,我們開發(fā)中認為 兩個對象如果 所有屬性值都一樣 認為是 同一個對象。
在我們觀點里面 stu2 stu4是同一個對象。
默認情況下沒有當成 同一個對象 并沒有完成 元素的去重
如果 想要達到開發(fā)標準 兩個對象屬性值都一樣 就是同一個對象怎么做?
重寫
hashCode() -- 目的 是要根據(jù)內(nèi)容算哈希值。
equals() -- 目的 是進行內(nèi)容比較。
重寫之后
stu2 stu4 先算出哈希值 哈希碰撞 位置一樣 再進行equals比較 內(nèi)容一樣不存
*/
for (Student student : set) {
System.out.println(student);
}
/*
存儲元素原理
先根據(jù)hashcode算出 存儲位置
位置上有元素 就進行equals比較。
*/
}
}
七.LinkedHashSet集合
????????依然是基于哈希表(數(shù)組、鏈表、紅黑樹)實現(xiàn)的
????????但是,它的每個元素都額外的多了一個雙鏈表的機制記錄它前后元素的位置
八.TreeSet集合
? ? ? ?1.?特點:不重復、無索引、可排序(默認升序排序 ,按照元素的大小,由小到大排序)
????????對于數(shù)值類型:Integer , Double,默認按照數(shù)值本身的大小進行升序排序。
????????對于字符串類型:默認按照首字符的編號升序排序。
?? ? ? ?2.底層是基于紅黑樹實現(xiàn)的排序。
? ? ? ? 3.TreeSet集合中對自定義類型元素排序方案:
????????方式一:讓自定義的類(如學生類)實現(xiàn)Comparable接口,重寫里面的compareTo方法來指定比較規(guī)則。
????????方式二:通過調(diào)用TreeSet集合有參數(shù)構(gòu)造器,可以設(shè)置Comparator對象(比較器對象,用于指定比較規(guī)則)
? ? ? ?
package com.itheima.day07.teacher.set03;
/**
學生類
*/
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;
}
/**
* 獲取
* @return name
*/
public String getName() {
return name;
}
/**
* 設(shè)置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 獲取
* @return age
*/
public int getAge() {
return age;
}
/**
* 設(shè)置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 獲取
* @return height
*/
public double getHeight() {
return height;
}
/**
* 設(shè)置
* @param height
*/
public void setHeight(double height) {
this.height = height;
}
public String toString() {
return "Student{name = " + name + ", age = " + age + ", height = " + height + "}";
}
@Override
public int compareTo(Student o) {
return this.age-o.age;//前-后 升序
}
}
-------------
package com.itheima.day07.teacher.set03;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo {
/*
TreeSet
底層是一個 二叉排序樹
遵循特點
小的存左邊 大的存右邊 一樣的不存
里面的存儲的元素必須具備 ??!排序功能!! 元素之間有大小關(guān)系
*/
public static void main(String[] args) {
TreeSet<Integer> set1 = new TreeSet<>();
set1.add(13);
set1.add(15);
set1.add(12);
set1.add(33);
set1.add(26);
set1.add(13);
set1.add(14);
System.out.println(set1);
/*
TreeSet去重原則 一樣的不存
存完之后元素進行排序
是因為 存儲的元素類型有排序規(guī)則
implements Comparable<Integer>
實現(xiàn) Comparable 代表有了排序的規(guī)則 所以可以使用TreeSet存儲
TreeSet 去重的原理
是排序的規(guī)則 如果一樣就不存。
*/
System.out.println("==========");
TreeSet<String> set2 = new TreeSet<>();
set2.add("cba");
set2.add("cbb");
set2.add("aba");
set2.add("bbb");
set2.add("cbb");
System.out.println(set2);
}
}
-------------
package com.itheima.day07.teacher.set03;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetDemo01 {
/*
開發(fā)中不建議 用TreeSet存儲自定義類型,因為會根據(jù)只定義排序內(nèi)容進行去重,與實際開發(fā)不符。
如果執(zhí)意要用 你就得對所有的 屬性進行排序比較 規(guī)則
如果要用TreeSet存自定義類型
1:自定義類型 實現(xiàn) Comparable接口 實現(xiàn)排序規(guī)則。
2:在 TreeSet 構(gòu)造中 寫出臨時的排序規(guī)則 傳遞規(guī)則Comparator接口。
*/
public static void main(String[] args) {
//創(chuàng)建學生對象
Student stu1 = new Student("小磊",18,1.88);
Student stu2 = new Student("小鑫",28,1.38);
Student stu3 = new Student("小哲",22,1.78);
Student stu4 = new Student("小迪",28,1.68);
//創(chuàng)建 TreeSet集合
TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.getAge()-o1.getAge();//按照年齡降序
}
});
//存元素
set.add(stu1);
set.add(stu2);
set.add(stu3);
set.add(stu4);
for (Student student : set) {
System.out.println(student);
}
}
}
Collection集合使用小結(jié):
????????1、如果希望記住元素的添加順序,需要存儲重復的元素,又要頻繁的根據(jù)索引查詢數(shù)據(jù)?
????????????????用ArrayList集合(有序、可重復、有索引),底層基于數(shù)組的。(常用)
????????2、如果希望記住元素的添加順序,且增刪首尾數(shù)據(jù)的情況較多?
????????????????用LinkedList集合(有序、可重復、有索引),底層基于雙鏈表實現(xiàn)的。
????????3.如果不在意元素順序,也沒有重復元素需要存儲,只希望增刪改查都快?
????????????????用HashSet集合(無序,不重復,無索引),底層基于哈希表實現(xiàn)的。(常用)
????????4.如果希望記住元素的添加順序,也沒有重復元素需要存儲,且希望增刪改查都快?
????????????????用LinkedHashSet集合(有序,不重復,無索引),底層基于哈希表和雙鏈表,
????????5.如果要對元素進行排序,也沒有重復元素需要存儲?且希望增刪改查都快?
????????????????用Treeset集合,基于紅黑樹實現(xiàn)。
集合的并發(fā)修改異常:
????????使用迭代器遍歷集合時,又同時在刪除集合中的數(shù)據(jù),程序就會出現(xiàn)并發(fā)修改異常的錯誤"王麻子”);("小李子");由于增強for循環(huán)遍歷集合就是迭代器遍歷集合的簡化寫法,因此,使用增強for循環(huán)遍歷("李愛花");在同時("張全蛋");("曉李");刪除集合中的數(shù)據(jù)時,程序也會出現(xiàn)并發(fā)修改異常的錯誤。("李玉剛");
怎么保證遍歷集合同時刪除數(shù)據(jù)時不出bug?
使用迭代器遍歷集合,但用迭代器自己的刪除方法刪除數(shù)據(jù)即可
如果能用for循環(huán)遍歷時:可以倒著遍歷并刪除;或者從前往后遍歷,但刪除元素后做i--操作
九.集合工具類Collections
????????Collections代表集合工具類,提供的都是靜態(tài)方法,用來操作集合元素的。
????????常用靜態(tài)方法:
public static <T> void sort(List<T> list):
????????????????數(shù)值型的List集合,按照值特性排序,默認升序
????????????????字符串的List集合,按照字符串元素的首字母編號排序。默認升序
????????????????對于自定義類型的集合,List<Student> ,默認報錯的解決方法
????????????????????????解決方式一:讓學生類實現(xiàn)比較規(guī)則Comparable接口。重寫比較方法。
????????????????????????解決方式二:可以讓sort方法自帶一個比較器
????????????????文章來源:http://www.zghlxwxcb.cn/news/detail-832729.html
package com.itheima.day07.teacher.other;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class EditException {
/*
并發(fā)修改異常
什么是并發(fā)修改異常:
ConcurrentModificationException
在使用迭代器(增強for) 遍歷元素的同時,通過集合對象刪除了集合中的指定數(shù)據(jù),
這個時候就會出現(xiàn)并發(fā)修改異常。
原因是什么:
迭代器里面 元素個數(shù) 和 集合中元素個數(shù)不一致了。
怎么避免并發(fā)修改異常:
在開發(fā)中不在迭代器 迭代過程中 使用集合刪除對象。
使用迭代器去刪 迭代器刪除的同時會給集合進行同步。
*/
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("name1");
list.add("name2");
list.add("name3");
list.add("name3");
list.add("name4");
list.add("name5");
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);
}
}
-------------
package com.itheima.day07.teacher.other;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class CollenctionsDemo {
/*
集合工具類使用
*/
public static void main(String[] args) {
//ArrayList集合 是Collection子類 也是List子類
List<String> list = new ArrayList<>();
//
// list.add("a"); 一個一個元素添加
//批量添加 Collections.addAll(Collection集合,T...t)//T 泛型的意思 集合里面是什么類型 泛型就是什么類型
Collections.addAll(list,"nba","cba","qba","abc");
System.out.println("查看集合內(nèi)容:"+list);
// 打亂順序方法 --針對有序集合的(List)
// Collections.shuffle(List集合)
Collections.shuffle(list);
System.out.println("打亂后集合內(nèi)容:"+list);
// 對集合元素排序 --針對有序集合(List)
// Collections.sort(List集合) 有前提 元素類型 具備排序規(guī)則 需要實現(xiàn)Comparable接口
Collections.sort(list); //按照默認順序 升序
System.out.println("排序之后:"+list);
// 臨時改變排序規(guī)則
// Collections.sort(List集合,Comparator接口實現(xiàn)類對象) 按照當前自己定義的排序規(guī)則排序
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);//字符串進行 降序 后面比較前面
}
});
System.out.println("自定義排序規(guī)則后:"+list);
}
}
????????文章來源地址http://www.zghlxwxcb.cn/news/detail-832729.html
到了這里,關(guān)于Collection集合體系(ArrayList,LinekdList,HashSet,LinkedHashSet,TreeSet,Collections)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!