集合
-
概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
-
和数组区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
-
位置:
java.util.*;
Collection体系集合
- [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXTrXLm3-1629187824176)(file://C:/Users/LXK/AppData/Roaming/Typora/typora-user-images/image-20210805092449217.png?lastModify=1628126803)]
Collection父接口
-
特点:代表一组任意类型的对象,无序、无下标、不能重复。
-
方法:
boolean add(Object obj)// 添加一个对象 boolean addAll(Collection c) // 将一个集合中的所有对象添加到此集合中。 void clear() // 清空此集合中的所有对象。 boolean contains(Object o) // 检查此集合中是否包含o对象。 boolean equals(Object o) // 比较此集合中是否与指定对象相等。 boolean isEmpty() // 判断此集合是否为空。 boolean remove(Object o) // 在此集合中移除o对象。 int size() // 返回此集合中的元素个数。 Object[] toArray() // 将此集合转换成数组。
-
package gather; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Collection接口的使用 * 1、添加元素 * 2、删除元素 * 3、遍历元素 * 4、判断 */ public class Test01 { public static void main(String[] args) { // 创建集合 Collection collection = new ArrayList(); // * 1、添加元素 collection.add("苹果"); collection.add("西瓜"); collection.add("榴莲"); System.out.println("元素个数:"+collection.size());//元素个数:3 System.out.println(collection);//[苹果, 西瓜, 榴莲] // * 2、删除元素 collection.remove("榴莲"); System.out.println("删除之后元素个数:"+collection.size());//删除之后元素个数:2 System.out.println(collection);//[苹果, 西瓜] // collection.clear(); // System.out.println("清空之后元素个数:"+collection.size()); // System.out.println(collection); // * 3、遍历元素【重点】 // (1)使用增强for System.out.println("----使用增强for遍历----"); for (Object o : collection) { System.out.println(o);//苹果 西瓜 } // (2)使用迭代器(专门用来遍历集合的方式) //1.hasNext();有没有下一个元素 //2.next(); 获取下一个元素 System.out.println("---使用Iterator迭代器---"); Iterator iterator = collection.iterator(); while (iterator.hasNext()){ String s = (String) iterator.next(); System.out.println(s);//苹果 西瓜 } //3.remove(); 删除当前元素 // System.out.println("-----删除-----"); // iterator.remove(); // System.out.println("删除后元素个数:"+collection.size());//删除后元素个数:1 // for (Object o : collection) { // System.out.println(o);//苹果 // } // System.out.println("-----清空-----"); // collection.clear(); // System.out.println("清空后元素个数:"+collection.size());// 清空后元素个数:0 // * 4、判断 System.out.println("-----判断-----"); System.out.println(collection.contains("苹果"));//true System.out.println(collection.isEmpty());// false } }
-
package gather.Student; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; /** * Collection的使用:保存学生信息 */ public class Test02 { public static void main(String[] args) { // 新建Collection对象 Collection collection = new ArrayList(); Student s1 = new Student("张三", 20); Student s2 = new Student("张无忌", 18); Student s3 = new Student("王二", 22); // 1.添加数据 collection.add(s1); collection.add(s2); collection.add(s3); System.out.println("元素个数"+collection.size());//元素个数3 System.out.println(collection.toString());// [Student [name=张三,age=20], Student [name=张无忌,age=18], Student [name=王二,age=22]] // 2.删除 collection.remove(s1); System.out.println("删除之后:"+collection.size());//删除之后:2 System.out.println(collection.toString());//[Student [name=张无忌,age=18], Student [name=王二,age=22]] // 清空,清空的是对象的地址(引用),对象本身并未删除。 // collection.clear(); // System.out.println("清空之后:"+collection.size());//清空之后:0 // 3.遍历 //1.增强for System.out.println("----增强for遍历----"); /* ----增强for遍历打印结果---- Student [name=张无忌,age=18] Student [name=王二,age=22] */ for (Object o : collection) { Student s = (Student) o; System.out.println(o.toString());// // System.out.println(o); } //2.迭代器:hasNext() next(); remove(); 迭代过程中不能使用collection的删除方法。 System.out.println("---迭代遍历---"); /* ----迭代器遍历打印结果---- Student [name=张无忌,age=18] Student [name=王二,age=22] */ Iterator iterator = collection.iterator(); while (iterator.hasNext()){ // 一定要强转换 Student student = (Student)iterator.next(); System.out.println(student.toString()); } // 4.判断 System.out.println(collection.contains(s1));// 被删除了,所以打印结果:false System.out.println(collection.contains(s2));// true System.out.println(collection.isEmpty()); // false } }
List子接口
-
特点:有序、有下标、元素可以重复。
-
方法:
-
void add(int index,Object o) // 在index位置插入对象o。 boolean addAll(int index,Colection c) // 将一个集合中的元素添加到此集合中的index位置。 Object get(int index) // 返回集合中指定位置的元素。 List subList(int fromIndex,int toIndex) // 返回fromIndex和toIndex之间的集合元素。
-
package gather.List; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; /** *List接口的使用 * 特点:1.有序有下标 2.可以重复 */ public class Test01 { public static void main(String[] args) { // 先创建集合对象 List list = new ArrayList<>(); //1.添加元素 list.add("苹果"); list.add("小米"); list.add("华为"); System.out.println("元素个数:"+list.size());//元素个数:3 System.out.println(list.toString());//[苹果, 小米, 华为] //2.删除元素 // list.remove("苹果"); // list.remove(0); // System.out.println("删除之后:"+list.size()); // System.out.println(list.toString()); // 3.遍历【重点】 //1.使用for遍历 System.out.println("---使用for遍历---"); for (int i = 0; i <list.size() ; i++) { System.out.println(list.get(i)); } // 2.使用增强for System.out.println("---使用增强for遍历---"); /* 打印结果为: 苹果 小米 华为 */ for (Object o : list) { System.out.println(o); } //3.使用迭代器 System.out.println("---使用迭代器遍历---"); /* 打印结果为: 苹果 小米 华为 */ Iterator iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } //4.使用列表迭代器(新增),和Iterator的区别。 //ListIterator可以向前或向后遍历,添加,删除,修改元素。 ListIterator listIterator = list.listIterator(); System.out.println("----使用列表迭代器从前往后----"); /* 打印结果为: 0:苹果 1:小米 2:华为 */ while (listIterator.hasNext()){ System.out.println(listIterator.nextIndex()+":"+listIterator.next()); } System.out.println("----使用列表迭代器从后往前----"); /* 打印结果为: 2:华为 1:小米 0:苹果 */ while (listIterator.hasPrevious()){ System.out.println(listIterator.previousIndex()+":"+listIterator.previous()); } //4.判断 System.out.println(list.contains("苹果"));//true System.out.println(list.isEmpty());//false //5.获取“华为”在集合的位置 System.out.println(list.indexOf("华为"));//2 } }
-
package gather.List; import java.util.ArrayList; import java.util.List; /** * List的使用 */ public class Test02 { public static void main(String[] args) { // 创建对象 List list = new ArrayList(); // 1.添加数字数据(自动装箱) list.add(20); list.add(30); list.add(40); list.add(50); list.add(60); System.out.println("元素个数:"+list.size());//元素个数:5 System.out.println(list.toString());//[20, 30, 40, 50, 60] // 2.删除操作 // list.remove(1); // System.out.println("元素个数:"+list.size());//元素个数:4 // System.out.println(list.toString());//[20, 40, 50, 60] // list.remove(new Integer(20)); // System.out.println("元素个数:"+list.size());//元素个数:4 // System.out.println(list.toString());//[30, 40, 50, 60] //3.补充方法subList,返回子集合,含头不含尾 List list1 = list.subList(1, 3); System.out.println(list1.toString());//[30, 40] } }
-
List实现类
-
ArrayList【重点】:
源码分析:默认容量DEFAULT_CAPACITY = 10;
注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素后容量为10,每次扩容大小为原来的1.5倍。
存放元素的数组 elementData
实际元素个数:size
package gather.ArrayList; import gather.Student.Student; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; /** * ArrayList的使用 * 存储结构:数组,查找遍历速度快、增删慢 */ public class Test01 { public static void main(String[] args) { //创建集合 ArrayList arrayList = new ArrayList<>(); //1.添加元素 Student s1 = new Student("刘德华",20); Student s2 = new Student("郭富城",22); Student s3 = new Student("梁朝伟",18); arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); System.out.println("元素个数"+arrayList.size());//元素个数3 System.out.println(arrayList.toString());//[Student [name=刘德华,age=20], Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]] //2.删除元素 // System.out.println("---删除元素---");; // arrayList.remove(s1); // System.out.println("删除之后元素个数:"+arrayList.size());//删除之后元素个数:2 // System.out.println(arrayList.toString());//[Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]] //3.遍历元素【重点】 //1.使用迭代器 System.out.println("---使用迭代器---"); /** * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ Iterator iterator = arrayList.iterator(); while (iterator.hasNext()){ Student student = (Student) iterator.next(); System.out.println(student.toString()); } //2.增强for遍历 /** *Student [name=刘德华,age=20] *Student [name=郭富城,age=22] *Student [name=梁朝伟,age=18] */ // System.out.println("---使用增强for循环---"); // for (Object o : arrayList) { // Student o1 = (Student) o; // System.out.println(o1.toString()); // } // 3.列表迭代器 /** * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ System.out.println("---使用列表迭代器遍历---"); ListIterator listIterator = arrayList.listIterator(); while (listIterator.hasNext()){ Student student = (Student) listIterator.next(); System.out.println(student.toString()); } //4.列表迭代器逆序 /** * Student [name=梁朝伟,age=18] * Student [name=郭富城,age=22] * Student [name=刘德华,age=20] */ System.out.println("---逆序---"); while (listIterator.hasPrevious()){ Student student = (Student) listIterator.previous(); System.out.println(student.toString()); } // 判 断 System.out.println(arrayList.contains(s1));//true System.out.println(arrayList.isEmpty());//false //查找 System.out.println(arrayList.indexOf(s2));//1 } }
- 数组结构实现,查询快、增删慢;
- JDK1.2版本,运行效率快,线程不安全。
-
Vector:
- 数组结构实现,查询快,增删慢;
- JDK1.0版本,运行效率慢、线程安全。
package Vector;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
/**
* 演示Vector集合的使用
* 存储结构:数组
*/
public class Test01 {
public static void main(String[] args) {
// 创建集合
Vector vector = new Vector<>();
//1.添加元素
vector.add("草莓");
vector.add("芒果");
vector.add("西瓜");
System.out.println("元素个数:"+vector.size());//元素个数:3
// 2.删除
// vector.remove(0);
// vector.remove("西瓜");
// vector.clear();
// 3.遍历
System.out.println("---增强for循环遍历---");
/**
* ---增强for循环遍历---
* 草莓
* 芒果
* 西瓜
*/
for (Object o : vector) {
String str = (String)o;
System.out.println(str.toString());
}
System.out.println("---使用迭代器遍历---");
/**
* ---使用迭代器遍历---
* 草莓
* 芒果
* 西瓜
*/
Iterator iterator = vector.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("---使用枚举器遍历---");
/**
* ---使用枚举器遍历---
* 草莓
* 芒果
* 西瓜
*/
Enumeration elements = vector.elements();
while (elements.hasMoreElements()){
// Object o = elements.nextElement();
// String str = (String) o;
String str =(String) elements.nextElement();
System.out.println(str);
}
// 4.判 断
System.out.println(vector.contains("西瓜"));//true
System.out.println(vector.isEmpty());//false
}
}
-
LinkedList:
- 链表结构实现,增删快,查询相对慢。
package LinkedList; import gather.Student.Student; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; /** * LinkList的使用 * 存储结构:双向链表 */ public class Test01 { public static void main(String[] args) { // 创建集合 LinkedList linkedList = new LinkedList<>(); //1.添加元素 Student s1 = new Student("刘德华",20); Student s2 = new Student("郭富城",22); Student s3 = new Student("梁朝伟",18); linkedList.add(s1); linkedList.add(s2); linkedList.add(s3); System.out.println("元素个数"+linkedList.size());//元素个数3 System.out.println(linkedList.toString());//[Student [name=刘德华,age=20], Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]] //2.删除 // linkedList.remove(s1); // System.out.println("元素个数"+linkedList.size());//元素个数2 // System.out.println(linkedList.toString());//[Student [name=郭富城,age=22], Student [name=梁朝伟,age=18]] //3.遍历 //使用for遍历 System.out.println("---使用for遍历---"); /** * ---使用for遍历--- * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ for (int i = 0; i <linkedList.size() ; i++) { System.out.println(linkedList.get(i)); } //使用增强for遍历 System.out.println("---使用增强for遍历---"); /** * ---使用增强for遍历--- * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ for (Object o : linkedList) { Student student = (Student)o; System.out.println(student.toString()); } //使用迭代器 System.out.println("---使用迭代器遍历---"); /** * ---使用迭代器遍历--- * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ Iterator iterator = linkedList.iterator(); while (iterator.hasNext()){ Student student = (Student)iterator.next(); System.out.println(student.toString()); } //使用listIterator列表迭代器遍历 System.out.println("---使用列表迭代器遍历---"); /** * ---使用列表迭代器遍历--- * Student [name=刘德华,age=20] * Student [name=郭富城,age=22] * Student [name=梁朝伟,age=18] */ ListIterator listIterator = linkedList.listIterator(); while (listIterator.hasNext()){ Student student1 = (Student)listIterator.next(); System.out.println(student1.toString()); } System.out.println("---逆序---"); /** * ---逆序--- * Student [name=梁朝伟,age=18] * Student [name=郭富城,age=22] * Student [name=刘德华,age=20] */ while (listIterator.hasPrevious()){ Student student1 = (Student)listIterator.previous(); System.out.println(student1.toString()); } //4.判断 System.out.println(linkedList.contains(s1));//true System.out.println(linkedList.isEmpty());//false //5.获取 System.out.println(linkedList.indexOf(s2));//1 } }
泛型
-
Java泛型是JDK1.5中引入的一个新特性,其本质是参数类型,把类型作为参数传递。
-
常见形式有泛型类、泛型接口、泛型方法。
-
语法:
- <T,…> T称为类型占位符,表示一种引用类型。
-
package gather.FanXing; public class TestGeneric { public static void main(String[] args) { //使用泛型类T来创建对象 /* 注意: 1.泛型只能使用引用类型。 2.不同泛型类型对象之间不能相互赋值。 */ MyGeneric<String> myGeneric = new MyGeneric<String>(); myGeneric.t = "Hello"; myGeneric.show("大家好,加油!"); String string = myGeneric.getT(); MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>(); myGeneric1.t = 100; myGeneric1.show(200); Integer integer = myGeneric1.getT(); } }
package gather.FanXing; /** * 泛型类 * 语法:类名<T,...> * T表示类型占位符,表示一种引用类型,若编写多个,使用逗号隔开。 */ // 泛型类 public class MyGeneric<T> { // 使用泛型T(不能实例化) //1.创建变量 T t; //2.泛型作为方法的参数 public void show(T t){ System.out.println(t); } //3.泛型作为方法的返回值 public T getT(){ return t; } }
-
泛型接口:
-
package gather.FanXing; public class TestGeneric { public static void main(String[] args) { //使用泛型类T来创建对象 /* 注意: 1.泛型只能使用引用类型。 2.不同泛型类型对象之间不能相互赋值。 */ MyGeneric<String> myGeneric = new MyGeneric<String>(); myGeneric.t = "Hello"; myGeneric.show("大家好,加油!");// 大家好,加油! String string = myGeneric.getT(); MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>(); myGeneric1.t = 100; myGeneric1.show(200);//200 Integer integer = myGeneric1.getT(); // 泛型接口,参数类型已经固定 MyInterfaceTest test = new MyInterfaceTest(); test.server("xxxxx");//xxxxx // 两个泛型类,参数类型为任意类型 MyInterfaceTest2 test2 = new MyInterfaceTest2(); test2.server(10000);//100000 } }
package gather.FanXing; /** * 泛型接口 * 语法:接口名<T> * 注意:不能使用泛型来创建静态常量 */ public interface MyInterface<T> { String name = "张三"; T server(T t); }
package gather.FanXing; public class TestGeneric { public static void main(String[] args) { //使用泛型类T来创建对象 /* 注意: 1.泛型只能使用引用类型。 2.不同泛型类型对象之间不能相互赋值。 */ MyGeneric<String> myGeneric = new MyGeneric<String>(); myGeneric.t = "Hello"; myGeneric.show("大家好,加油!");// 大家好,加油! String string = myGeneric.getT(); MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>(); myGeneric1.t = 100; myGeneric1.show(200);//200 Integer integer = myGeneric1.getT(); // 泛型接口,参数类型已经固定 MyInterfaceTest test = new MyInterfaceTest(); test.server("xxxxx");//xxxxx // 两个泛型类,参数类型为任意类型 MyInterfaceTest2 test2 = new MyInterfaceTest2(); test2.server(10000);//100000 } }
package gather.FanXing; public class MyInterfaceTest2<T> implements MyInterface<T> { @Override public T server(T t) { System.out.println(t); return t; } }
-
-
泛型方法:
-
package gather.FanXing; public class TestGeneric { public static void main(String[] args) { //泛型方法 类型与传递的参数有关 MyGenericMethod myGenericMethod = new MyGenericMethod(); myGenericMethod.show(12); } }
package gather.FanXing; /** * 泛型方法 * 语法:<T>,返回值类型 */ public class MyGenericMethod { // 泛型方法 public <T> void show(T t){ System.out.println("泛型方法"); return; } }
-
-
好处:
- 提高代码的重要性
- 防止类型转换异常,提高代码的安全性
泛型集合
-
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
-
特点:
- 编译时及时检查,并非运行时抛出异常。
- 访问时,不必类型转换(拆箱)。
- 不同泛型之间引用不能相互赋值,泛型不存在多态。
Set集合概述
Set子接口
-
特点:无序、无下标、元素不可重复。
-
方法:全部继承自Collection中的方法
package gather.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 测试Set接口的使用
* 特点:(1)无序 、没有下标 (2)不能重复
*/
public class Test01 {
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<>();
//1.添加数据
set.add("华为");
// set.add("华为");
set.add("苹果");
set.add("小米");
System.out.println("数据个数"+set.size());//数据个数3
System.out.println(set.toString());//[苹果, 华为, 小米]
//2.删除数据
// set.remove("小米");
// System.out.println(set.toString());
//3.遍历【重点】
//使用增强for
/**
* ---使用增强for循环遍历---
* 苹果
* 华为
* 小米
*/
System.out.println("---使用增强for循环遍历---");
for (String s : set) {
System.out.println(s);
}
//使用迭代器
/**
* ---使用迭代器遍历---
* 苹果
* 华为
* 小米
*/
System.out.println("---使用迭代器遍历---");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//4.判断
System.out.println(set.contains("华为"));//true
System.out.println(set.isEmpty());//false
}
}
Set实现类
-
HashSet【重点】
-
基于HashCode实现元素不重复。
-
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。
-
package gather.Set; import java.util.HashSet; import java.util.Iterator; /** * HashSet集合的使用 * 存储结构:哈希表(数组+链表+红黑树) */ public class Test02 { public static void main(String[] args) { //新建集合 HashSet<String> hashSet = new HashSet<>(); //1.添加元素 hashSet.add("刘德华"); hashSet.add("林志玲"); hashSet.add("周润发"); hashSet.add("梁朝伟"); // hashSet.add("刘德华");//不允许重复 System.out.println("元素个数:"+hashSet.size());//元素个数:4 System.out.println(hashSet.toString());//[林志玲, 梁朝伟, 周润发, 刘德华] //2.删除数据 hashSet.remove("刘德华"); System.out.println("元素个数:"+hashSet.size());//元素个数:3 System.out.println(hashSet.toString());//[林志玲, 梁朝伟, 周润发] //3.遍历 //增强for循环遍历 /** * ---增强for循环遍历--- * 林志玲 * 梁朝伟 * 周润发 */ System.out.println("---增强for循环遍历---"); for (String s : hashSet) { System.out.println(s); } //迭代器遍历 /** * ----使用迭代器遍历---- * 林志玲 * 梁朝伟 * 周润发 */ System.out.println("----使用迭代器遍历----"); Iterator<String> iterator = hashSet.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } //4.判断 System.out.println(hashSet.contains("郭富城"));//false } }
-
package gather.Set; import java.util.HashSet; /** * * HashSet集合的使用 * * 存储结构:哈希表(数组+链表+红黑树) * 存储过程: * (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步 * (2)在执行eqyals方法,如果equals方法为true,则认为是重复,否则,形成链表 */ public class Test03 { public static void main(String[] args) { //创建集合 HashSet<Persion> persions = new HashSet<>(); //1.添加集合 Persion persion = new Persion("刘德华",20); Persion persion1 = new Persion("林志玲",18); Persion persion2 = new Persion("梁朝伟",22); persions.add(persion); persions.add(persion1); persions.add(persion2); // persions.add(persion2);//重复,不能添加 persions.add(new Persion("梁朝伟",22)); System.out.println("元素个数:"+persions.size()); System.out.println(persions.toString()); } }
package gather.Set; /** * 人类 */ public class Persion { private String name; private int age; public Persion() { } public Persion(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Persion [name="+name+", age="+age+"]"; } @Override public int hashCode() { int n1 = this.name.hashCode(); int n2 = this.age; return n1+n2; } @Override public boolean equals(Object obj) { if (this==obj){ return true; } if (obj==null){ return false; } if (obj instanceof Persion){ Persion p = (Persion)obj; if (this.name.equals(p.getName())&&this.age ==p.getAge()){ return true; } } return false; } }
-
-
TreeSet:
- 基于排列顺序实现元素不重复。
- 实现了SortedSet接口,对集合元素自动排序。
- 元素对象的类型必须实现Comparable接口,指定排序规则。
- 通过CompareTo方法确定是否为重复元素。
-
package gather.Set; import java.util.TreeSet; /** * * TreeSet的使用 * * 存储结构:红黑树 * 要求:元素必须实现Comparable接口,compareTo()方法返回值为0,认为是重复元素 */ public class Test05 { public static void main(String[] args) { //1.创建集合 TreeSet<Persion> persions = new TreeSet<>(); Persion persion = new Persion("lxk",20); Persion persion1 = new Persion("abc",18); Persion persion2 = new Persion("zeh",22); Persion persion3 = new Persion("zeh",24); persions.add(persion); persions.add(persion1); persions.add(persion2); persions.add(persion3); System.out.println("元素个数"+persions.size()); System.out.println(persions.toString()); //2.删除 persions.remove(persion1); System.out.println(persions.size()); } }
package gather.Set; /** * 人类 */ public class Persion implements Comparable<Persion> { private String name; private int age; public Persion() { } public Persion(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Persion [name="+name+", age="+age+"]"; } @Override public int hashCode() { int n1 = this.name.hashCode(); int n2 = this.age; return n1+n2; } @Override public boolean equals(Object obj) { if (this==obj){ return true; } if (obj==null){ return false; } if (obj instanceof Persion){ Persion p = (Persion)obj; if (this.name.equals(p.getName())&&this.age ==p.getAge()){ return true; } } return false; } // 先按姓名比,再按年龄比 @Override public int compareTo(Persion o) { int n1 = this.getName().compareTo(o.getName()); int n2 = this.age-o.getAge(); return n1 == 0 ? n2 : n1; } }
comparator:是实现定制比较器
/** * TreeSet集合的使用 * Comparator:是实现定制比较(比较器) * Comparable:可比较的 */ public class Test06 { public static void main(String[] args) { // 创建集合并制定比较规则 TreeSet<Persion> persions = new TreeSet<>(new Comparator<Persion>() { @Override public int compare(Persion o1, Persion o2) { int n1 = o1.getAge()-o2.getAge(); int n2 = o1.getName().compareTo(o2.getName()); return n1==0? n2 : n1; } });
TreeSet案例
package gather.Set.anli; import java.util.Comparator; import java.util.TreeSet; /** * 要求:使用TreeSet集合实现字符串按照长度排序 * helloworld zhang lisi wangwu beijing xian nanjing * Comparator接口实现定制比较 */ public class Test07 { public static void main(String[] args) { //创建集合,并制定比较规则 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; } }); // 添加数据 treeSet.add("helloworld"); treeSet.add("pingguo"); treeSet.add("lisi"); treeSet.add("zhangsan"); treeSet.add("beijing"); treeSet.add("cat"); treeSet.add("nanjing"); treeSet.add("xian"); System.out.println(treeSet.toString()); } }
Map集合
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zDeUmSPn-1629187824178)(C:\Users\LXK\AppData\Roaming\Typora\typora-user-images\image-20210807104200341.png)]
- Map接口特点:
- 用于存储任意键值对(Key-Value)
- 键:无序、无下标、不允许重复(唯一)
- 值:无序、无下标、允许重复
Map接口
-
特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。
-
方法:
-
V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。 Object get(Object key) // 根据键获取对应的值。 KeySet<K> // 返回所有key。 Collection<V> values() //返回包含所有值的Collection集合。 Set<Map,Entry<K,V>> // 键值匹配的Set集合。
-
-
package gather.Map; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * Map接口的使用 * 特点:1.存储键值对 2.键不能重复,值可以重复 3.无序 */ public class Test01 { public static void main(String[] args) { //创建Map集合 Map<String, String> map = new HashMap<>(); //1.添加元素 map.put("cn","中国"); map.put("uk","英国"); map.put("usa","美国"); map.put("cn","zhongguo");//键唯一,把前面的“中国”替换掉了 System.out.println("元素个数:"+map.size());//元素个数:3 System.out.println(map.toString());//{usa=美国, uk=英国, cn=zhongguo} // 2.删除 // map.remove("usa"); // System.out.println("删除之后:"+map.size());//删除之后:2 // System.out.println(map.toString());//{uk=英国, cn=zhongguo} //3.遍历 //3.1使用keySet(); /** * usa---美国 * uk---英国 * cn---zhongguo */ System.out.println("---使用keySet遍历---");//---使用keySet遍历--- Set<String> keySet = map.keySet(); for (String key : keySet) { System.out.println(key+"---"+map.get(key)); } //3.2使用entrySet()方法 /** * ---使用entrySet()方法--- * usa----美国 * uk----英国 * cn----zhongguo */ System.out.println("---使用entrySet()方法---"); Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { System.out.println(entry.getKey()+"----"+entry.getValue()); } //4.判断 System.out.println(map.containsKey("cn"));//true System.out.println(map.containsKey("泰国"));//false } }
Map集合的实现类
-
HashMap【重点】:
-
JDK1.2版本,线程不安全,运行效率快:允许用null去哦为key或是value。
-
package gather.Map; import gather.Set.Persion; import java.util.HashMap; import java.util.Map; /** * HashMap集合的使用 * 存储结构:哈希表(数组+链表+红黑树) * 使用key的hashcode和equals作为重复依据 */ public class Test02 { public static void main(String[] args) { // 创建集合 HashMap<Student, String> students = new HashMap<Student,String>(); //添加元素 Student s1 = new Student("孙悟空",100); Student s2 = new Student("猪八戒",101); Student s3 = new Student("沙和尚",102); // Student s4 = new Student("沙和尚",102); students.put(s1,"北京"); students.put(s2,"上海"); students.put(s3,"杭州"); // students.put(s4,"北京"); // students.put(s3,"南京"); students.put(new Student("沙和尚",102),"周口");//因为key不能重复,覆盖了原先的杭州 System.out.println("元素个数:"+students.size());//素个数:3 System.out.println(students.toString());//{Student [name=猪八戒,sno=101]=上海, Student [name=沙和尚,sno=102]=周口, Student [name=孙悟空,sno=100]=北京} //删除 // students.remove(s1); // System.out.println("元素个数:"+students.size()); // System.out.println(students.toString()); //遍历 //1.使用keySet(); System.out.println("---使用keySet遍历---"); /** * ---使用keySet遍历--- * Student [name=猪八戒,sno=101]===上海 * Student [name=沙和尚,sno=102]===周口 * Student [name=孙悟空,sno=100]===北京 */ for (Student key : students.keySet()) { System.out.println(key.toString()+"==="+students.get(key)); } //2.使用entrySet() System.out.println("---使用entrySet遍历---"); /** * ---使用entrySet遍历--- * Student [name=猪八戒,sno=101]-----上海 * Student [name=沙和尚,sno=102]-----周口 * Student [name=孙悟空,sno=100]-----北京 */ for (Map.Entry<Student, String> entry : students.entrySet()) { System.out.println(entry.getKey()+"-----"+entry.getValue()); } //判断 System.out.println(students.containsKey(s1));//true System.out.println(students.containsValue("杭州"));//false System.out.println(students.isEmpty());//false } }
package gather.Map; import java.util.Objects; public class Student { private String name; private int sno; public Student(String name, int sno) { this.name = name; this.sno = sno; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSno() { return sno; } public void setSno(int sno) { this.sno = sno; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return sno == student.sno && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, sno); } @Override public String toString() { return "Student [name=" + name + ",sno=" + sno + "]"; } }
-
源码分析
默认初始化容量:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
数组最大容量:static final int MAXIMUM_CAPACITY = 1 << 30;
默认加载因子:static final float DEFAULT_LOAD_FACTOR = 0.75f;
链表调整为红黑树的链表长度阈值(JDK1.8):static final int TREEIFY_THRESHOLD = 8;
红黑树调整为链表的链表长度阈值(JDK1.8):static final int UNTREEIFY_THRESHOLD = 6;
链表调整为红黑树的数组最小阈值(JDK1.8):static final int MIN_TREEIFY_CAPACITY = 64;
HashMap存储的数组:transient Node<K,V>[] table;
HashMap存储的元素个数:transient int size;
总结
HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
jdk1.8 当链表长度 <6 时 调整成链表
jdk1.8 以前,链表时头插入,之后为尾插入
Map集合的实现类
- HashMap【重点】:
- JDK1.2版本,线程不安全,运行效率快:允许用null去哦为key或是value。
- Hashtable:
- JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value。
- Properties:
- Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
- TreeMap:
- 实现了SortedMap接口(是Map的子接口),可以对key自动排序。
Collection工具类
-
概念:集合工具类,定义了除了存储以外的集合常用方法。
-
方法:
-
public static void reverse(List<?> list) //反转集合中元素的排序 public static void shuffle(List<?> list) // 随机重置集合元素的排序 public static void sort(List<T> list) // 升序排序(元素类型必须实现Compare接口)
-
-
package gather.Map.Collection; import java.util.*; /** * 演示Collection工具类的使用 */ public class Test { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(20); list.add(5); list.add(13); list.add(30); list.add(4); list.add(6); //sort排序前 System.out.println(list.toString());//[20, 5, 13, 30, 4, 6] Collections.sort(list);//[4, 5, 6, 13, 20, 30] //排序后 System.out.println(list.toString());//3 //binarySearch 二分查找 int i = Collections.binarySearch(list,13); System.out.println(i); int j = Collections.binarySearch(list,12); System.out.println(j);//-4(不存在,为负数) //copy 复制 List<Integer> list1 = new ArrayList<>(); for (int k = 0; k <list.size() ; k++) { list1.add(0); } Collections.copy(list1,list); System.out.println(list1.toString());//[4, 5, 6, 13, 20, 30] //reverse反转 Collections.reverse(list); System.out.println("反转之后:"+list);//反转之后:[30, 20, 13, 6, 5, 4] //shuffle 打乱 Collections.shuffle(list); System.out.println("打乱之后:"+list);//打乱之后:[6, 13, 5, 4, 30, 20] // 补充:1.list转为数组 Integer[] arr = list.toArray(new Integer[0]); System.out.println(arr.length);//6 System.out.println("转为数组之后"+Arrays.toString(arr));//转为数组之后[6, 13, 5, 4, 30, 20] //数组转为list String[] name = {"张三","李四","王二"}; List<String> list2 = Arrays.asList(name); // 受限集合:不能添加和删除 System.out.println("数组转集合:"+list2);//数组转集合:[张三, 李四, 王二] //基本类型数组在转成集合时,需要修改为包装类型 Integer[] nums = {100,200,300,400,500}; List<Integer> list3 = Arrays.asList(nums); System.out.println(list3); } }
集合总结
- 集合的概念:
- 对象的容器,和数组类似,定义了多个对象进行操作的常用方法。
- List集合:
- 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
- Set集合:
- 无序、无下标、元素不可重复。(HashSet、TreeSet)
- Map集合:
- 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
- Collections:
- 集合工具类,定义了除了存储以外的集合常用方法。
int j = Collections.binarySearch(list,12);
System.out.println(j);//-4(不存在,为负数)
//copy 复制
List list1 = new ArrayList<>();
for (int k = 0; k <list.size() ; k++) {
list1.add(0);
}
Collections.copy(list1,list);
System.out.println(list1.toString());//[4, 5, 6, 13, 20, 30]
//reverse反转
Collections.reverse(list);
System.out.println(“反转之后:”+list);//反转之后:[30, 20, 13, 6, 5, 4]
//shuffle 打乱
Collections.shuffle(list);
System.out.println(“打乱之后:”+list);//打乱之后:[6, 13, 5, 4, 30, 20]
// 补充:1.list转为数组
Integer[] arr = list.toArray(new Integer[0]);
System.out.println(arr.length);//6
System.out.println(“转为数组之后”+Arrays.toString(arr));//转为数组之后[6, 13, 5, 4, 30, 20]
//数组转为list
String[] name = {“张三”,“李四”,“王二”};
List list2 = Arrays.asList(name);
// 受限集合:不能添加和删除
System.out.println(“数组转集合:”+list2);//数组转集合:[张三, 李四, 王二]
//基本类型数组在转成集合时,需要修改为包装类型
Integer[] nums = {100,200,300,400,500};
List list3 = Arrays.asList(nums);
System.out.println(list3);
}
}
- 集合工具类,定义了除了存储以外的集合常用方法。
集合总结
- 集合的概念:
- 对象的容器,和数组类似,定义了多个对象进行操作的常用方法。
- List集合:
- 有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
- Set集合:
- 无序、无下标、元素不可重复。(HashSet、TreeSet)
- Map集合:
- 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
- Collections:
- 集合工具类,定义了除了存储以外的集合常用方法。