目录
马上就要考核了,总结整理一下关于集合的笔记吧,感觉好不清晰![]()
●Collection(单列集合)
●List
●Set
●Map (双列集合)

一、Collection
1.Collection是单列集合的祖宗接口,它的功能是全部单列集合都可以继承使用的。
2.它还有两个子接口List<E>接口和Set<E>接口,所以Collection中的方法对他们来说是通用的。
List系列集合:添加的元素是有序、可重复、有索引
Set系列集合:添加的元素是无序,不重复、无索引
3.两个子接口又分别有各自对应的实现类
List 接口 java.util.ArrayList java.util.LinkedList
Set 接口 java.util.HashSet java.util.LinkedHashSet java.util.TreeSet。
二、List
数组列表类ArrayList<E> 底层采用数组实现,查询快,增删慢
链表类 LinkedList<E> 底层采用双向链表实现,查询慢,增删快
如何选用
ArrayList<E> 通过下标随机访问元素,除了在末尾之外,不在其他位置插入或删除元素
LinkedList<E> 需要在任意位置进行插入或删除操作
List系列集合独有的方法:
void add(int index,E element) 在此集合中的指定位置插入指定的元素
E remove(int index) 删除指定索引处的元素,返回被蹦除的元素
E set(int index,E element) 修改指定索引处的元素,返回被修改的元素
E get(int index) 返回指定索引处的元素
import java.util.ArrayList;
import java.util.List;
public class ListDemo01{
public static void main(String[] args){
//创建集合并添加元素
List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
//1. 在指定位置插入指定的元素 原来索引上的元素会依次往后移
list.add(1,"qqq");
//2. 删除指定索引处的元素,返回被删除的元素
//请问:此时删除的是1这个元素,还是1索引上的元素?为什么?
//因为在调用方法的时候,如果方法出现了重载现象 优先调用,实参跟形参类型一致的那个方法。
list.remove(1);
String remove =list.remove(1);
System.out.println(remove);
//3. 修改指定索引处的元素,返回被修改的元素
list.set(0,"nnn");
String result =list.set(0,"nnn");
System.out.println(result);
list.get(2);
String result1 =list.get(2);
System.out.println(result1);
}
}
三、Set
1.Set系列集合的特点
无序:存取顺序不一致
不重复:可以去除重复
无索引:没有带索引的方法,所以不能使用普通for循环遍历,也不能通过索引来获取元素
2.Set集合的实现类
HashSet:无序、不重复、无索引
LinkedHashSet:有序、不重复、无索引
TreeSet:可排序、不重复、无索引
Set接口中的方法上基本上与Collection的API一致。
⑴HashSet集合
底层原理 哈希表
⑵LinkedHashSet集合
-
LinkedHashSet集合的原理 底层基于哈希表,使用双链表记录添加顺序
-
在以后如果要数据去重,默认使用HashSet 如果要求去重且存取有序,才使LinkedHashSet
⑶TreeSet集合
不仅实现了Set<E>接口,还实现了java.util,SortedSet接口
TreeSet的特点
●不重复、无索引、可排序
●可排序:按照元素的默认规则(有小到大)排序。
●TreeSet集合底层是基升红黑树的数据结构实现排序的,增删改查性能都较好。
Treeset集合默认的规则
●对于数值类型: Integer , Double,默认按照从小到大的顺序进行排序。
●对于字符、字符串类型:按照字符在ASCII码表中的数字升序进行排序。
TreeSet集合自定义排序规则有几种方式
●方式一: 创建集合时,自定义Comparator比较器对象,指定比较规则
import java.util.TreeSet;
import java.util.Comparator;
public class TreeSetDemo02{
public static void main(String[] args){
/*需求:请自行选择比较器排序和自然排序两种方式;
要求:存入四个字符串,按照长度排序,如果一样长则按照首字母排序
采取第二种排序方式:比较器排序*/
//创建集合
//o1:表示当前要添加的元素
//o2:表示已经在红黑树存在的元素
//返回值规则跟以前是一样的
TreeSet<String> ts = new TreeSet<>(new Comparator<String>(){
public int compare(String s1,String s2){
//按照长度排序
int i =s1.length()-s2.length();
//如果一样长则按照首字母排序
i = i== 0?s1.compareTo(s2):i;
return i;
}
});
//添加元素
ts.add("zdv");
ts.add("zv");
ts.add("sfgb");
ts.add("gfgbbf");
ts.add("n");
//打印集合
System.out.println(ts);
●方式二:Javabean类实现Comparable接口,指定比较规则
/*需求:创建5个学生对象
属性:(姓名,年龄,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台
如果总分一样,按照语文成绩排
如果语文一样,按照数学成绩排
如果数学成绒一样,按照英语成绩排
如果英文成绩一样,按照年龄排
如果年龄一样,按照姓名的字母顺序排
如果都一样,认为是同一个学生,不存。*/
import java.util.TreeSet;
import java.util.Iterator;
class Student implements Comparable<Student>{
private String name;
private int age;
private int chinese;
private int math;
private int english;
protected Student(){}
protected Student(String name,int age,int chinese,int math,int english){
this.name = name;
this.age = age;
this.chinese = chinese;
this.math = math;
this.english=english;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setChinese(int chinese){
this.chinese = chinese;
}
public int getChinese(){
return chinese;
}
public void setMath(int math){
this.math = math;
}
public int getMath(){
return math;
}
public void setEnglish(int math){
this.english = english;
}
public int getEnglish(){
return english;
}
//重写compareTo方法
public int compareTo(Student o){
int sum1 = this.getChinese()+this.getMath()+this.getEnglish();
int sum2 =o.getChinese()+o.getMath()+o.getEnglish();
int i = sum1-sum2;
i = i==0?this.getChinese()-o.getChinese():i;
i = i==0?this.getMath()-o.getMath():i;
i = i==0?this.getEnglish()-o.getEnglish():i;
i=i ==0?this.getAge()-o.getAge():i;
i=i==0?this.getName().compareTo(o.getName()):i;
return i;
}
public String toString(){
return "学生姓名"+name+",年龄"+age+",语文成绩"+chinese+",数学成绩"+math+",英语成绩"+english;
}
}
public class TreeSetDemo03{
public static void main(String[] args){
//创建学生对象
Student s1 = new Student("小一",12,60,80,86);
Student s2 = new Student("小十",12,56,54,89);
Student s3 = new Student("小土",12,57,89,54);
Student s4 = new Student("男巫",45,68,86,86);
Student s5 = new Student("菲尔夏鸟",99,32,45,96);
//创建集合并添加元素
TreeSet<Student> ts = new TreeSet<>();
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
ts.add(s5);
//打印集合
//System.out.println(ts);
/* for(Student s : ts){
System.out.println(s);
} */
Iterator<Student> s =ts.iterator();
while(s.hasNext()){
Student u =s.next();
System.out.println(u);
}
}
}
3.使用场景
1.如果想要集合中的元素可重复
●用ArrayList集合,基于数组的。(用的最多)
2.如果想要集合中的元素可重复,而且当前的增删操作明显多于查询
●用LinkedList集合,基于链表的。
3.如果想对集合中的元素去重
●用HashSet集合,基于哈希表的。(用的最多)
4.如果想对集合中的元素去重,而且保证存取顺序
●用LinkedHashSet集合,基于哈希表和双链表,效率低于Hashset。
5.如果想对集合中的元素进行排序
●用Treeset集合,基于红黑树。后续也可以用List集合实现排序。
四、Map
1.Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的
双列集合的特点
①双列集合一次需要存一对数据,分别为键和值
②键不能重复,值可以重复
③键和值是一一对应的,每一个键只能找到自己对应的值 ④键+值这个整体我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”
put方法的细节:添加/覆盖 在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中 在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回。
import java.util.*;
public class MapDemo01{
public static void main(String[] args){
/*
v put(K key,v value) 添加元素
boolean v remove( object Key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(object Key) 判断集合是否包含指定的键
boolean containsValue(object Value) 判断集合是否包含指定的值
boolean isEmpty(o) 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数*/
//1.创建map集合的对象
Map<String,String> m = new HashMap<>();
//2.添加元素
/*put方法
put方法的细节:添加/覆盖
在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中,方法返回null
在添加数据的时候,如果键是存在的,那么会把原有的键值对对象覆盖,会把被覆盖的值进行返回*/
String value1 = m.put("顾拙言","庄凡心");
System.out.println(value1);//null
m.put("骆闻舟","陶然");
m.put("江停","严峫");
m.put("简隋英","李玉");
//3.返回被覆盖的值
String value2 = m.put("骆闻舟","费渡");
System.out.println(value2);//陶然
//4. v remove( object key)
String result = m.remove("骆闻舟");
System.out.println(result);//陶然(删除键,吧值进行返回;删除值,返回值为空)
// 5. void clear()
//m.clear();
//System.out.println(m);
//6.boolean containskey(object key)
boolean result1 = m.containsKey("简隋英");
System.out.println(result1);
//7.boolean containsValue(object Value)
boolean result2 = m.containsValue("李玉");
System.out.println(result2);
//8. boolean isEmpty(o)
boolean result3 = m.isEmpty();
System.out.println(result3);
int len =m.size();
System.out.println(len);
}
}
●HashMap的特点
①HashMap是Map里面的一个实现类。
②没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
③特点都是由键决定的:无序、不重复、无索引
④HashMap跟HashSet底层原理是一模一样的,都是哈希表结构-(底层是数组加链表,为了提高性能又加了红黑树)
import java.util.*;
class Student{
private String name;
private int age;
protected Student(){}
protected Student(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
//重写hashCode方法
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);
}
public int hashCode(){
return Objects.hash(name,age);
}
public String toString(){
return "Student{name="+name+",age ="+age+"}";
}
}
public class HashMapDemo01{
public static void main(String[] args){
//如果键存储的是自定义对象,需要重写hashCode和equals方法
//创建对象
Student s1 = new Student("费渡",22);
Student s2 = new Student("江停",35);
Student s3 = new Student("严峫",31);
Student s4 = new Student("严峫",31);
//创建集合
HashMap<Student,String> hm = new HashMap<>();
hm.put(s1,"燕城");
hm.put(s2,"恭州");
hm.put(s3,"建宁");
hm.put(s4,"津海");//键里面的数据是一样的,那么它就会覆盖原有的entry对象(这就是put方法隐藏的覆盖功能)。
//lambda表达式
hm.forEach((Student key,String value)->{
System.out.println(key+"="+value);
});
}
}
-
HashMap底层是哈希表结构的
-
依赖hashCode方法和equals方法保证键的唯一
-
如果键存储的是自定义对象,需要重写hashCode和equals方法 如果值存储自定义对象,不需要重写hashCode和equals方法
●LinkedHashMap
由键决定:有序、不重复、无索引。 这里的有序指的是保证存储和取出的元素顺序一致
原理︰底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。
●TreeMap
●TreeMap跟TreeSet底层原理一样,都是红黑树结构的。
●由键决定特性:不重复、无索引、可排序
●可排序:对键进行排序。
●注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则
代码书写两种排序规则
●实现Comparable接口,指定比较规则。
●创建集合时传递Comparator比较器对象,指定比较规则。
五、遍历
List系列集合的五种遍历方式:
1.迭代器 在遍历的过程中需要删除元素,请使用迭代器
2.列表迭代器 在遍历的过程中需要添加元素,请使用列表迭代器
3.增强for 4.Lambda表达式 仅仅想遍历,那么使用增强for或Lambda表达式。
5.普通for循环 如果遍历的时候想操作索引,可以用普通for。
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.function.Consumer;
import java.util.ListIterator;
public class ListDemo03{
public static void main(String[] args){
/* List系列集合的五种遍历方式:
1 .迭代器
2.列表迭代器
3.增强for
4.Lambda表达式
5.普通for循环*/
//创建集合并添加元素
List<String> list =new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//1.迭代器
Iterator<String> it=list.iterator();
while(it.hasNext()){
String str=it.next();
System.out.println(str);
}
//2.增强for循环
/*增强for格式
for(数据类型 变量名:集合/数组){
} */
for(String s:list){
System.out.println(s);
}
//3.Lambda表达式
//()->{}
list.forEach((String s)->{System.out.println(s);});
//4..普通for循环
for(int i = 0;i<list.size();i++){
String sr=list.get(i);
System.out.println(sr);
}
//5.列表迭代器
//获取一个迭代器的对象,里面的指针默认也是指向0索引的
//额外添加了一个方法,在遍历的过程中,可以添加元素
ListIterator<String> it = list.listIterator();
while(it.hasNext()){
String st=it.next();
if("bbb".equals(st)){
it.add("qqq");
}
}
System.out.println(list);
}
}
Set系列集合的三种遍历方式:
import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;
import java.util.function.Consumer;
public class SetDemo01{
public static void main(String[] args){
/*利用set系列的集合,添加字符串,并使用多种方式遍历
迭代器
增强for
Lambda表达式*/
//1.创建set集合的对象
Set<String> s = new HashSet<>();
//2.添加对象
//如果当前元素是第一次添加,那么可以添加成功,返回true
//如果当前元素是第二次添加,那么添加失败,返回false
s.add("张三");
s.add("张三");
s.add("李四");
s.add("王五");
//打印集合
//System.out.println(s);//李四 张三 王五(无重复,无序)
//迭代器遍历
Iterator<String> it = s.iterator();
while(it.hasNext()){//当前指针的位置是否有元素
String str = it.next();//调用方法,获取元素移动指针
System.out.println(str);
}
//增强for遍历
for(String st : s){
System.out.println(st);
}
//Lambda表达式
//匿名内部类
s.forEach(new Consumer<String>(){
public void accept(String sr){
System.out.println(sr);
}
});//new的是{public void accept(String sr){}}类的对象,str依次表示集合中的每一个元素*/
//Lambda表达式
s.forEach(str2->System.out.println(str2));
}
}
Map系列集合的三种遍历方式:
键找值
键值对
lambda表达式
import java.util.*;
import java.util.function.Consumer;
public class MapDemo02{
public static void main(String[] args){
/*三个课堂练习;
练习一:利用键找值的方式遍历map集合,要求:装着键的单列集合使用增强for的形式进行遍历
练习二:利用键找值的方式遍历map集合,要求:装着键的单列集合使用迭代器的形式进行遍历
练习三:利用键找值的方式遍历map集合,要求:装着键的单列集合使用1ambda表达式的形式进行遍历*/
//1.创建集合map的对象
Map<String,String> m= new HashMap<>();
//2.添加元素
m.put("骆闻舟","费渡");
m.put("江停","严峫");
m.put("简隋英","李玉");
//3.通过键找值
//3.1获取所有的键,把这些键放到一个单列集合中
Set<String> keys = m.keySet();
//3.2遍历单列集合,得到每一个键
for(String key : keys){
System.out.println(key);
//3.3利用map集合中的键获取对应的值get
String value = m.get(key);
System.out.println(key+"="+value);
}
//利用迭代器遍历
/Iterator<String> s =keys.iterator();//用集合调用方法获取迭代器的对象
while(s.hasNext()){
String str =s.next();//遍历得到每一个键
String value = m.get(str);//利用map集合中的键获取对应的值get
System.out.println(str+"="+value);
}
//利用1ambda表达式的形式进行遍历
/*keys.forEach(new Consumer<String>(){
public void accept(String key){
String value = m.get(key);
System.out.println(key+"="+value);
}
});*/
keys.forEach((String key)->{
String value = m.get(key);
System.out.println(key+"="+value);
});
}
}
import java.util.*;
import java.util.function.Consumer;
public class MapDemo03{
public static void main(String[] args){
//三个课堂练习
//练习一;通过键值对对象进行遍历map集合,要求:装着键值对对象的单列集合使用增强for的形式进行遍历
//练习二:通过键值对对象进行遍历map集合,要求:装着键值对对象的单列集合使用迭代器的形式进行遍历
//练习三:通过键值对对象进行遍历map集合,要求:装着键值对对象的单列集合使用1ambda的形式进行遍历
//1. 创建Map集合的对象
Map<String,String> map = new HashMap<>();
//2. 添加元素
map.put("骆闻舟","费渡");
map.put("严峫","江停");
map.put("顾昀","长庚");
//3. Map集合的第二种遍历方式
//通过键值对对象进行遍历
//3.1 通过一个方法获取所有键值对对象,返回一个set集合
Set<Map.Entry<String,String>> entries = map.entrySet();
//用map集合调用entrySet方法,获取所有键值对对象
//装在一个set集合里面,然后返回
//entry是map接口里面的内部接口,需要用Map.接口来调用
//Map.可以省略,但要导包 import java.util.Map.Entry;
//3.2 遍历集合,得到每一个键值对对象
for(Map.Entry<String,String> entry : entries){
//3.3 利用entry 调用get方法来获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
//4. 利用迭代器遍历
Iterator<Map.Entry<String,String>> str =entries.iterator();//用集合调用方法获取迭代器的对象
while(str.hasNext()){
Map.Entry<String,String> s = str.next();//遍历得到每一个键值对对象
String key = s.getKey();//利用s 调用get方法来获取键和值
String value =s.getValue();
System.out.println(key+"="+value);
}
//利用1ambda的形式进行遍历
//用匿名内部类
entries.forEach(new Consumer<Map.Entry<String,String>>(){
public void accept(Map.Entry<String,String> entry){
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+value);
}
});
}
}
import java.util.*;
import java.util.function.BiConsumer;
public class MapDemo04{
public static void main(String[] args){
//创建集合
Map<String,String> map = new HashMap<>();
//添加对象
map.put("骆闻舟","费渡");
map.put("严峫","江停");
map.put("顾昀","长庚");
//利用lambda遍历
map.forEach((String key,String value)->{
System.out.println(key+"="+value);
});
//利用lambda遍历
//匿名内部类
/*map.forEach(new BiConsumer<String,String>(){
public void accept(String key,String value){
System.out.println(key+"="+value);
}
});*/
}
本文围绕Java集合展开,介绍了Collection、List、Set、Map等集合类型。阐述了各集合特点、实现类及使用场景,如ArrayList查询快、LinkedList增删快等。还提及TreeSet自定义排序规则,以及各系列集合的遍历方式,为Java开发者提供集合使用参考。
1259





