集合
概念:對(duì)象的容器,定義了多個(gè)對(duì)象進(jìn)行操作的常用方法,類似數(shù)組功能
和數(shù)組的區(qū)別
1、數(shù)組長(zhǎng)度固定,集合長(zhǎng)度不固定
2、數(shù)組可以存儲(chǔ)基本類型和引用類型,集合只能存儲(chǔ)引用類型位置:java.util.*
Collection體系集合

Collection
- 特點(diǎn):代表一組任意類型的對(duì)象,無(wú)序、無(wú)下標(biāo)、不能重復(fù)
-
方法
- Collection的使用
student類
package Collection;
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@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 && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
迭代器(Iterator<E>)
hasNext():如果仍有元素可以迭代,則返回 true
next():返回迭代的下一個(gè)元素。
Collection.Demo1
package Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Collection接口的使用
* 1、添加元素
* 2、刪除元素
* 3、遍歷元素
* 4、判斷
*/
public class Demo01 {
public static void main(String[] args) {
//創(chuàng)建集合
Collection collection = new ArrayList();
// 添加元素
collection.add("蘋果");
collection.add("西瓜");
collection.add("榴蓮");
System.out.println("元素個(gè)數(shù):" + collection.size());
System.out.println(collection);
// 刪除元素
// collection.remove("榴蓮");
// collection.clear(); //刪除全部
// System.out.println("刪除之后:" + collection.size());
// 遍歷元素
System.out.println("3.1使用增強(qiáng)for");
for(Object object : collection){
System.out.println(object);
}
System.out.println("3.2使用迭代器(迭代器專門用來(lái)遍歷集合的一種方式");
/*hasNext();有沒(méi)有下一個(gè)元素
* next()獲取下一個(gè)元素
* remove()刪除當(dāng)前元素
* 使用迭代器不能使用collection的其他方法:collection.remove()
* */
Iterator it = collection.iterator();
while(it.hasNext()){
String s = (String) it.next();
System.out.println(s);
//it.remove();
}
System.out.println("元素個(gè)數(shù):" + collection.size());
// 判斷
System.out.println(collection.contains("西瓜")); //true
System.out.println(collection.isEmpty()); //false
}
}
Collection.Demo2
package Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* Collection的使用:保存學(xué)生信息
*
*/
public class Demo02 {
public static void main(String[] args) {
//新建Collection對(duì)象
Collection collection = new ArrayList();
Student s1 = new Student("張三",20);
Student s2 = new Student("阿貍",18);
Student s3 = new Student("王二",22);
//添加數(shù)據(jù)
collection.add(s1);
collection.add(s2);
collection.add(s3);
System.out.println("元素個(gè)數(shù):" + collection.size());
System.out.println(collection.toString());
//刪除
//collection.remove(new Student("王二",22)); //這樣不能刪除
//collection.clear(); //實(shí)際上是刪除地址指針
System.out.println("刪除之后:" + collection.size());
//遍歷
System.out.println("for循環(huán)");
for(Object object : collection){
Student s = (Student) object;
System.out.println(s.toString());
}
System.out.println("迭代器");
Iterator it = collection.iterator();
while(it.hasNext()){
Student s = (Student) it.next();
System.out.println(s.toString());
}
//判斷
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
Collection子接口
List集合
- 特點(diǎn):有序、有下標(biāo)、元素可以重復(fù)
-
方法:
- List的使用
ListIterator 方法更強(qiáng)大
hasNext(): 以正向遍歷列表時(shí),如果列表迭代器有多個(gè)元素,則返回 true(換句話說(shuō),如果 <tt>next</tt> 返回一個(gè)元素而不是拋出異常,則返回true)。
hasPrevious():如果以逆向遍歷列表,列表迭代器有多個(gè)元素,則返回 true。
next():返回列表中的下一個(gè)元素。
previous():返回列表中的上一個(gè)元素。
Collection.Demo3
package Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/**
* List的子接口的使用
* 特點(diǎn):1、有序有下標(biāo) 2、可以重復(fù)
*/
public class Demo3 {
public static void main(String[] args) {
//先創(chuàng)建集合對(duì)象
List list = new ArrayList();
// 添加元素
list.add("蘋果");
list.add("小米");
list.add("華為");
System.out.println("元素個(gè)數(shù):" + list.size());
System.out.println(list.toString());
//刪除元素
// list.remove("蘋果");
// list.remove(0);
// System.out.println("刪除之后:" + list.size());
//遍歷
System.out.println("----for循環(huán)----");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
System.out.println("----增強(qiáng)for----");
for(Object object : list){
System.out.println(object);
}
System.out.println("----迭代器----");
Iterator it = list.iterator();
while(it.hasNext()){
Object s = it.next();
System.out.println(s);
}
System.out.println("----列表迭代器-----");
/*
可向前遍歷,也可以向后遍歷 添加、刪除、修改元素
*/
ListIterator lit = list.listIterator();
System.out.println("----從前往后");
while(lit.hasNext()){
System.out.println(lit.nextIndex() + ":" + lit.next());
}
System.out.println("----從后往前");
while(lit.hasPrevious()){
System.out.println(lit.previousIndex() + ":" + lit.previous());
}
// 判斷
System.out.println(list.contains("蘋果"));
System.out.println(list.isEmpty());
// 獲取位置
System.out.println(list.indexOf("華為"));
}
}
Collection.Demo4
package Collection;
import java.util.ArrayList;
import java.util.List;
/**
* List的使用
*/
public class Demo4 {
public static void main(String[] args) {
List list = new ArrayList();
//添加數(shù)字?jǐn)?shù)據(jù)(自動(dòng)裝箱)
list.add(10);
list.add(20);
list.add(30);
list.add(40);
list.add(50);
System.out.println("元素個(gè)數(shù)+"+list.size());
System.out.println(list.toString());
//刪除
// list.remove(new Integer(20)); // 直接寫20會(huì)被當(dāng)成下標(biāo)
// System.out.println(list.toString());
//補(bǔ)充方法subList 返回子集合,含頭不含尾
List subList = list.subList(1, 3);
System.out.println(subList.toString());
}
}
List實(shí)現(xiàn)類
ArrayList、Vector、LinkedList對(duì)比


ArrayList
- ArrayList的使用
Collction.Demo5
package Collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/**
* ArrayList的使用
* 存儲(chǔ)結(jié)構(gòu):數(shù)組, 查找遍歷速度快,增刪慢
*/
public class Demo5 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList<>();
//添加
Student s1 = new Student("劉德華",20);
Student s2 = new Student("郭富城",22);
Student s3 = new Student("梁朝偉",23);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println("元素個(gè)數(shù):" + arrayList.size());
System.out.println(arrayList.toString());
//刪除
// arrayList.remove(s1);
// arrayList.remove(new Student("劉德華",20));
// System.out.println("刪除后:"+arrayList.toString()); // 重寫student的equals方法,equals+enter就出來(lái)了
// 遍歷元素
System.out.println("----迭代器----");
Iterator it = arrayList.iterator();
while(it.hasNext()){
Student s = (Student) it.next();
System.out.println(s.toString());
}
System.out.println("----列表迭代器----");
ListIterator lit = arrayList.listIterator();
System.out.println("----從前往后");
while(lit.hasNext()){
System.out.println(lit.nextIndex() + ":" + lit.next());
}
System.out.println("----從后往前");
while(lit.hasPrevious()){
System.out.println(lit.previousIndex() + ":" + lit.previous());
}
//判斷
System.out.println(arrayList.contains(new Student("劉德華", 20)));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(new Student("劉德華", 20)));
}
}
- ArrayList源碼分析
- 默認(rèn)容量:
private static final int DEFAULT_CAPACITY = 10;
添加元素后才有默認(rèn)容量,沒(méi)添加元素時(shí),元素為0
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
- 存放容量的數(shù)組:Object[] elementData
- size:列表實(shí)際元素個(gè)數(shù)
- add():添加元素
- grow():oldCapacity >> 1 右移一位就是除以2 ,自動(dòng)擴(kuò)容為原來(lái)的1.5倍
Vector
- Vector的使用
Vector.Demo1
package Vector;
import java.beans.VetoableChangeListener;
import java.util.Enumeration;
import java.util.Vector;
/**
* Vector集合的使用
* 存儲(chǔ)結(jié)構(gòu):數(shù)組
*/
public class Demo1 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素個(gè)數(shù):" + vector.size());
System.out.println(vector.toString());
// vector.remove(0);
// vector.remove("西瓜");
// vector.clear();
// 遍歷
Enumeration en = vector.elements();
while(en.hasMoreElements()){
String o =(String) en.nextElement();
System.out.println(o);
}
System.out.println(vector.contains("西瓜"));
System.out.println(vector.isEmpty());
// 其他方法
System.out.println(vector.firstElement());
System.out.println(vector.lastElement());
}
}
LinkedList
- LinkedList的使用
Collection.Demo6
package Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* LinkedList的使用
* 存儲(chǔ)結(jié)構(gòu):雙向鏈表
*/
public class Demo6 {
public static void main(String[] args) {
LinkedList linkedList = new LinkedList();
Student s1 = new Student("劉德華",20);
Student s2 = new Student("郭富城",22);
Student s3 = new Student("梁朝偉",23);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
System.out.println("元素個(gè)數(shù):" + linkedList.size());
System.out.println(linkedList.toString());
// linkedList.remove(s1);
// linkedList.remove(new Student("劉德華",20));
// linkedList.clear();
// for遍歷
System.out.println("----for循環(huán)----");
for(int i=0;i<linkedList.size();i++){
System.out.println(linkedList.get(i));
}
System.out.println("----增強(qiáng)for----");
for(Object s:linkedList){
System.out.println(s);
}
System.out.println("----迭代器----");
Iterator it = linkedList.iterator();
while(it.hasNext()){
Student s = (Student) it.next();
System.out.println(s);
}
System.out.println("----列表迭代器----");
ListIterator lit = linkedList.listIterator();
System.out.println("----從前往后");
while(lit.hasNext()){
System.out.println(lit.nextIndex() + ":" + lit.next());
}
System.out.println("----從后往前");
while(lit.hasPrevious()){
System.out.println(lit.previousIndex() + ":" + lit.previous());
}
// 判斷
System.out.println(linkedList.contains(s1));
System.out.println(linkedList.isEmpty());
// 獲取
System.out.println(linkedList.indexOf(s2));
}
}
- LinkedList源碼分析
- int size:集合大小
- Node first:鏈表的頭節(jié)點(diǎn)
- Node last:鏈表 的尾節(jié)點(diǎn)
Set集合
- 特點(diǎn):無(wú)序、無(wú)下標(biāo)、元素不可重復(fù)
- 方法:全部繼承collection的方法
- Set接口的使用
Set.Demo1
package Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 測(cè)試set接口的使用
* 特點(diǎn):1、無(wú)序、無(wú)下標(biāo)2、不能重復(fù)
*/
public class Demo1 {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
//添加數(shù)據(jù)
set.add("華為");
set.add("蘋果");
set.add("小米");
System.out.println(set.toString()); //打印是無(wú)序的
//刪除
// set.remove("小米");
// System.out.println(set.toString());
// set.clear();
//遍歷
System.out.println("----增強(qiáng)for----");
for(String s:set){
System.out.println(s);
}
System.out.println("----迭代器----");
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(set.contains("華為"));
System.out.println(set.isEmpty());
}
}
HashSet
- 基于HashCode計(jì)算元素存放位置。
- 當(dāng)存入元素的哈希碼相同時(shí),會(huì)調(diào)用equals進(jìn)行確認(rèn),如結(jié)果為true,則拒絕后者存入。
Set.Demo2
package Set;
import java.util.HashSet;
import java.util.Iterator;
/**
* HashSet集合的使用
* 存儲(chǔ)結(jié)構(gòu):哈希表(數(shù)組+鏈表+紅黑樹)
*/
public class Demo2 {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
//添加
hashSet.add("劉德華");
hashSet.add("梁朝偉");
hashSet.add("劉志玲");
hashSet.add("周潤(rùn)發(fā)");
System.out.println(hashSet.toString());
//刪除
// hashSet.remove("劉德華");
// hashSet.clear();
//遍歷
System.out.println("----增強(qiáng)for----");
for(String s:hashSet){
System.out.println(s);
}
System.out.println("----迭代器----");
Iterator<String> it = hashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(hashSet.contains("華為"));
System.out.println(hashSet.isEmpty());
}
}
Set.Person
package Set;
import java.util.Objects;
public class Person implements Comparable<Person>{
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
//先按姓名比,再按年齡比
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.age-o.getAge();
return n1==0?n2:n1;
}
}
Set.Demo3
package Set;
import java.util.HashSet;
/**
* hashSet的使用
* 存儲(chǔ)結(jié)構(gòu):哈希表(數(shù)組+鏈表+紅黑樹)
* 存儲(chǔ)過(guò)程:
* 1)根據(jù)hashcode計(jì)算保存的位置,如果此位置為空,則直接保存,如果不為空?qǐng)?zhí)行第二步
* 2)再執(zhí)行equals方法,如果equals方法為true,則認(rèn)為是重復(fù),否則,形成鏈表
*/
public class Demo3 {
public static void main(String[] args) {
HashSet<Person> persons = new HashSet<>();
Person p1 = new Person("劉德華",20);
Person p2 = new Person("郭富城",22);
Person p3 = new Person("梁朝偉",23);
persons.add(p1);
persons.add(p2);
persons.add(p3);
//persons.add(p3) //不可以添加
persons.add(new Person("梁朝偉",23)); // 可以添加,重寫equals和hashcode就不可以添加了
System.out.println(persons.toString());
// 刪除
// persons.remove(p1);
// persons.remove(new Person("梁朝偉",23));
}
}
TreeSet
- 基于排列順序?qū)崿F(xiàn)元素不重復(fù)
- 實(shí)現(xiàn)類SortSet接口,對(duì)集合元素自動(dòng)排序
- 元素對(duì)象的類型必須實(shí)現(xiàn)Comparable接口,指定排序規(guī)則
- 通過(guò)CompareTo方法確定是否為重復(fù)元素
Set.Demo4
package Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet的使用
* 存儲(chǔ)結(jié)構(gòu):紅黑樹
*/
public class Demo4 {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("hello");
treeSet.add("xyz");
System.out.println(treeSet.toString());
//遍歷
System.out.println("----增強(qiáng)for----");
for(String s:treeSet){
System.out.println(s);
}
System.out.println("----迭代器----");
Iterator<String> it = treeSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(treeSet.contains("abc"));
System.out.println(treeSet.isEmpty());
}
}
Set.Demo5
package Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet保存數(shù)據(jù)
* 存儲(chǔ)結(jié)構(gòu):紅黑樹
* 要求:元素必須實(shí)現(xiàn)Comparable接口,compareTo()的返回值為0,認(rèn)為是重復(fù)元素
*/
public class Demo5 {
public static void main(String[] args) {
TreeSet<Person> persons = new TreeSet<>();
Person p1 = new Person("劉德華",20);
Person p2 = new Person("郭富城",22);
Person p3 = new Person("梁朝偉",23);
persons.add(p1);
persons.add(p2);
persons.add(p3);
//persons.add(p3) //不可以添加
persons.add(new Person("梁朝偉",23)); // 可以添加,重寫equals和hashcode就不可以添加了
System.out.println(persons.toString());
// 刪除
// persons.remove(p1);
// persons.remove(new Person("梁朝偉",23));
// System.out.println(persons.toString());
//遍歷
System.out.println("----增強(qiáng)for----");
for(Person p:persons){
System.out.println(p);
}
System.out.println("----迭代器----");
Iterator<Person> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(persons.contains(p1));
System.out.println(persons.isEmpty());
}
}
實(shí)現(xiàn)定制比較器
Set.Demo6
package Set;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/**
* TreeSet保存數(shù)據(jù)
* Comparator:實(shí)現(xiàn)定制比較(比較器
* Comparable:可比較的
*/
public class Demo6 {
public static void main(String[] args) {
TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1=o1.getAge()-o2.getAge();
int n2=o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Person p1 = new Person("劉德華",20);
Person p2 = new Person("郭富城",22);
Person p3 = new Person("梁朝偉",23);
persons.add(p1);
persons.add(p2);
persons.add(p3);
//persons.add(p3) //不可以添加
persons.add(new Person("梁朝偉",23)); // 可以添加,重寫equals和hashcode就不可以添加了
System.out.println(persons.toString());
// 刪除
// persons.remove(p1);
// persons.remove(new Person("梁朝偉",23));
// System.out.println(persons.toString());
//遍歷
System.out.println("----增強(qiáng)for----");
for(Person p:persons){
System.out.println(p);
}
System.out.println("----迭代器----");
Iterator<Person> it = persons.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//判斷
System.out.println(persons.contains(p1));
System.out.println(persons.isEmpty());
}
}
Set.Demo7
package Set;
import java.util.Comparator;
import java.util.TreeSet;
/**
* 要求:使用TreeSet集合實(shí)現(xiàn)字符串按照長(zhǎng)度進(jìn)行排序
* helloworld zhang lisi wangwu beijing xian nanjing
*
*/
public class Demo7 {
public static void main(String[] args) {
//創(chuàng)建集合,制定比較規(guī)則
TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1=o1.length()-o2.length();
int n2=o1.compareTo(o2);
return n1==0?n2:n1; //如果n1==0,證明長(zhǎng)度相等則比較string
}
});
treeSet.add("helloword");
treeSet.add("pingguo");
treeSet.add("lisi");
treeSet.add("zhangsan");
treeSet.add("cat");
treeSet.add("nanjing");
treeSet.add("ali");
System.out.println(treeSet.toString());
}
}
Map集合
-
特點(diǎn)
1.用于存儲(chǔ)任意鍵值對(duì)(Key-Value)。
2.鍵:無(wú)序、無(wú)下標(biāo)、不允許重復(fù)(唯一)。
3.值:無(wú)序、無(wú)下標(biāo)、允許重復(fù)。
Map父接口
- 特點(diǎn):存儲(chǔ)一對(duì)數(shù)據(jù)(key-value),無(wú)序、無(wú)下標(biāo),鍵不可以重復(fù),值可以重復(fù)
-
方法:
-
Map的使用
map.keySet():把所有的key拿出來(lái)放到Set集合里面(key和value分開(kāi)遍歷)
map.entrySet():把key和value封裝成一個(gè)個(gè)entry(效率高)
map.Demo1
package map;
import java.util.HashMap;
import java.util.Map;
/**
* Map接口的使用
* 特點(diǎn):1、存儲(chǔ)鍵值對(duì) 2、鍵不能重復(fù),值可以 3、無(wú)序
*/
public class Demo1 {
public static void main(String[] args) {
//創(chuàng)建Map集合
Map<String,String> map = new HashMap<>();
map.put("cn", "中國(guó)");
map.put("uk","英國(guó)");
map.put("usa","美國(guó)");
map.put("cn","zhongguo"); //不能共存會(huì)把前面的替換掉
System.out.println(map.toString());
//刪除
// map.remove("usa");
//遍歷
System.out.println("----keySet()----");
// Set<String> keyset = map.keySet();
for(String key:map.keySet()){
System.out.println(key+":"+map.get(key));
}
System.out.println("-----entrySet()----");
// Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry<String,String> entry : map.entrySet()){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("泰國(guó)"));
}
}
HashMap
- HashMap的使用
map.Student
package map;
import java.util.Objects;
public class Student {
private String name;
private int stuNo;
public Student() {
}
public Student(String name, int stuNo) {
this.name = name;
this.stuNo = stuNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getStuNo() {
return stuNo;
}
public void setStuNo(int stuNo) {
this.stuNo = stuNo;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", stuNo=" + stuNo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return stuNo == student.stuNo && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, stuNo);
}
}
map.Demo2
package map;
import java.util.HashMap;
import java.util.Map;
/**
* HashMap集合的使用
* 存儲(chǔ)結(jié)構(gòu):哈希表(數(shù)組+鏈表+紅黑樹)
*/
public class Demo2 {
public static void main(String[] args) {
HashMap<Student,String> studens = new HashMap<>();
//剛創(chuàng)建HashMap table=null =>size=0
Student s1 = new Student("孫悟空",101);
Student s2 = new Student("豬八戒",102);
Student s3 = new Student("沙和尚",103);
studens.put(s1,"北京");
studens.put(s2,"上海");
studens.put(s3,"杭州");
System.out.println(studens.toString());
//刪除
// studens.remove(s1);
//遍歷
System.out.println("----keySet()----");
// Set<String> keyset = map.keySet();
for(Student key:studens.keySet()){
System.out.println(key+":"+studens.get(key));
}
System.out.println("-----entrySet()----");
// Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry<Student,String> entry : studens.entrySet()){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 判斷
System.out.println(studens.containsKey(new Student("孫悟空",101)));
System.out.println(studens.containsValue("上海"));
}
}
- HashMap的源碼分析
-
初始大小為16(1<<4 : 1X2**4)
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 1 -
最大值為1<<30
static final int MAXIMUM_CAPACITY = 1 << 30; -
默認(rèn)加載因子為0.75(容量使用超過(guò)75%就擴(kuò)容)
static final float DEFAULT_LOAD_FACTOR = 0.75f; -
數(shù)組長(zhǎng)度大于64,鏈表長(zhǎng)度大于8,鏈表變成紅黑樹,鏈表長(zhǎng)度小于6,調(diào)整為數(shù)組
static final int TREEIFY_THRESHOLD = 8; static final int UNTREEIFY_THRESHOLD = 6; static final int MIN_TREEIFY_CAPACITY = 64; HashMap存儲(chǔ)的數(shù)組:transient Node<K,V>[] table;
HashMap存儲(chǔ)的元素個(gè)數(shù):transient int size;
-
HashSet實(shí)際上用的HashMap,它的方法add用的是HashMap的put
public HashSet() {
map = new HashMap<>();
}
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
總結(jié)
1.HashMap剛創(chuàng)建時(shí),table是null,為了節(jié)省空間,當(dāng)添加第一個(gè)元素時(shí),table容量調(diào)為16
2.當(dāng)元素個(gè)數(shù)大于閾值(16*0.75=12)時(shí),會(huì)進(jìn)行擴(kuò)容,擴(kuò)容后大小為原來(lái)的2倍,目的時(shí)減少調(diào)整元素的個(gè)數(shù)
3.jdk1.8當(dāng)每個(gè)鏈表長(zhǎng)度大于8,并且元素個(gè)數(shù)大于等于64時(shí),會(huì)調(diào)整為紅黑樹,目的提高執(zhí)行效率
4.jdk1.8當(dāng)鏈表長(zhǎng)度小于6時(shí),調(diào)整成鏈表
5.jdk1.8以前,鏈表時(shí)頭插入,jdk1.8之后是尾插入
TreeMap
- TreeSet的使用
map.Demo3
package map;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
/**
* TreeMap的使用
* 存儲(chǔ)結(jié)構(gòu):紅黑樹
*/
public class Demo3 {
public static void main(String[] args) {
TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1=o1.getName().compareTo(o2.getName());
int n2 = o1.getStuNo()-o2.getStuNo();
return n1==0?n2:n1;
}
});
Student s1 = new Student("孫悟空",101);
Student s2 = new Student("豬八戒",102);
Student s3 = new Student("沙和尚",103);
treeMap.put(s1,"北京");
treeMap.put(s2,"上海");
treeMap.put(s3,"杭州");
System.out.println(treeMap.toString());
// treeMap.remove(s3);
// treeMap.remove(new Student("孫悟空",101));
//遍歷
System.out.println("----keySet()----");
// Set<String> keyset = map.keySet();
for(Student key:treeMap.keySet()){
System.out.println(key+":"+treeMap.get(key));
}
System.out.println("-----entrySet()----");
// Set<Map.Entry<String,String>> entries = map.entrySet();
for(Map.Entry<Student,String> entry : treeMap.entrySet()){
System.out.println(entry.getKey() + ":" + entry.getValue());
}
// 判斷
System.out.println(treeMap.containsKey(new Student("孫悟空",101)));
System.out.println(treeMap.containsValue("上海"));
}
}

Collections工具類
- 概念:集合工具類,定義除了存取以外的集合常用方法
-
方法:
image.png - Collections類的使用
map.Demo4
package map;
import java.util.*;
/**
* 演示Colletions工具類的使用
*/
public class Demo4 {
public static void main(String[] args) {
List<Integer> list= new ArrayList<>();
list.add(20);
list.add(5);
list.add(12);
list.add(30);
list.add(6);
System.out.println("排序之前:" + list.toString());
// sort排序
Collections.sort(list);
System.out.println("排序之后:" + list.toString());
//binarySearch
int i = Collections.binarySearch(list,12);
System.out.println(i);
//copy復(fù)制
List<Integer> dest = new ArrayList<>();
for(int k=0;k<list.size();k++){
dest.add(0);
}
Collections.copy(dest, list);
System.out.println(dest.toString());
//reverse反轉(zhuǎn)
Collections.reverse(list);
System.out.println("反轉(zhuǎn)之后:" + list.toString());
//shuffle 打亂
Collections.shuffle(list);
System.out.println("打亂之后:" + list);
//補(bǔ)充:list轉(zhuǎn)數(shù)組 new的那個(gè)數(shù)組長(zhǎng)度小于list的長(zhǎng)度的話,arr的長(zhǎng)度等于list的長(zhǎng)度,否則是new數(shù)組的長(zhǎng)度
Integer[] arr = list.toArray(new Integer[0]);
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
//數(shù)組轉(zhuǎn)集合
String[] name = {"張三","李四","王五"};
//集合是一個(gè)受限集合,不能添加刪除
List<String> list2 = Arrays.asList(name);
System.out.println(list2.toString());
//基本類型數(shù)組轉(zhuǎn)成集合時(shí),需要修改為包裝類 int=>Integer
Integer[] nums ={100,200,300,400,500};
List<Integer> list3 = Arrays.asList(nums);
}
}
集合總結(jié)

泛型
- Java泛型是JDK1.5中引入的一個(gè)新特性,其本質(zhì)是參數(shù)化類型,把類型作為參數(shù)傳遞
- 常見(jiàn)形式有泛型類、泛型接口、泛型方法
- 好處
1、提高代碼的重用性
2、防止類型轉(zhuǎn)換異常,提高代碼的安全性
泛型類
Generic.MyGeneric
package Generic;
/**
* 泛型類
* 語(yǔ)法:類名<T,E>
* T是類型占位符,表示一種引用類型,如果編寫多個(gè)用逗號(hào)隔開(kāi)
*/
public class MyGeneric<T> {
//使用泛型T
//1、創(chuàng)建遍歷
T t;
//2、作為方法的參數(shù)
public void show(T t){
System.out.println(t);
}
//3、使用泛型作為方法的返回值
public T getT(){
return t;
}
}
Generic.TestGeneric 部分代碼
//使用泛型類創(chuàng)建對(duì)象
MyGeneric<String> myGeneric = new MyGeneric<String>();
myGeneric.t = "hello";
myGeneric.show("大家好,加油");
System.out.println(myGeneric.getT());
MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
myGeneric2.t = 10;
myGeneric2.show(20);
System.out.println(myGeneric2.getT());
- 泛型只能使用引用類型
- 不同泛型對(duì)象不能相互復(fù)制(錯(cuò)誤: MyGeneric<String> myGeneric3 = myGeneric2;)
泛型接口
Generic.MyInterface
package Generic;
/**
* 泛型接口
* 語(yǔ)法:接口名<T>
*注意:不能泛型靜態(tài)常量
*/
public interface MyInterface <T> {
String name = "張三";
T sever(T t);
}
- 在實(shí)現(xiàn)類的時(shí)候確定類型
Generic.MyInterfaceImpl
package Generic;
public class MyInterfaceImpl implements MyInterface<String>{
@Override
public String sever(String s) {
System.out.println(s);
return s;
}
}
Generic.TestGeneric 部分代碼
MyInterfaceImpl impl = new MyInterfaceImpl();
impl.sever("阿貍");
- 實(shí)現(xiàn)類也是泛型類,在創(chuàng)建對(duì)象時(shí)確定類型
Generic.MyInterfaceImpl2
public class MyInterfaceImpl2<T> implements MyInterface<T>{
@Override
public T sever(T t) {
System.out.println(t);
return t;
}
}
Generic.TestGeneric 部分代碼
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<Integer>();
impl2.sever(10);
泛型方法
可以放在參數(shù)可以放在返回值,類型由傳遞值決定
Generic.MyGenericMethod
package Generic;
/**
* 泛型方法
* 語(yǔ)法:<T>返回值類型
*/
public class MyGenericMethod {
//泛型方法
public <T> T show(T t){
System.out.println("泛型方法"+t);
return t;
}
}
Generic.TestGeneric 部分代碼
//泛型方法的使用
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("中國(guó)加油");
myGenericMethod.show(200);
myGenericMethod.show(3.14);
泛型集合
- 概念:參數(shù)化類型、類型安全的集合,強(qiáng)制集合元素的類型必須一致。
- 特點(diǎn):
1、編譯時(shí)即可檢查,而非運(yùn)行時(shí)拋出異常。
2、訪問(wèn)時(shí),不必類型轉(zhuǎn)換(拆箱)。
3、不同泛型指尖引用不能相互賦值,泛型不存在多態(tài)。
筆記來(lái)源于b站視頻https://www.bilibili.com/video/BV1zD4y1Q7Fw?p=1





