目录
1.集合基础
当数组满了时,再加入新的数据会报错,因为数组不会自动扩容。此时可以使用集合,它可以自动扩容。
1.1ArrayList构造方法
构造一个初始容量为10的空列表
集合容器如果没有加入<>就可以存储任意数据类型
<>泛型:对集合容器存储的数据类型进行限制,只能写引用数据类型,不能写基本数据类型
格式:ArrayList<String>,限制此集合只能存储String类型的变量
1.2成员方法
方法名 | 说明 |
public ArrayList() | 创建一个空的集合对象 |
public boolean add(E e) | 将指定的元素追加到此集合的末尾 |
public void add(int index E element) | 在此集合中的指定位置插入指定的元素 |
pubic boolean remove(Object o) | 删除指定的元素,返回删除是否成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
2.Collection
2.1数组和集合的区别
相同点:都是容器,可以存储多个数据
不同点:数组长度是不可变的,集合的长度是可变的
数组可以存基本数据类型和引用数据类型
集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包
2.2集合体系结构
集合:Collection,Map
List,Set;HashMap,TreeMap
ArrayList,LinkedList;HashSet,TreeSet
2.3集合常用方法
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
boolean removeIf(Object o) | 根据条件进行移除 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
3.遍历
3.1迭代器
集合的专用遍历方式,Iterator<E> iterator(): 返回此集合中元素的迭代器,通过集合对象的iterator()方法得到
常用方法:
boolean hasNext(): 判断当前位置是否有元素可以被取出
E next(): 获取当前位置的元素,将迭代器对象移向下一个索引位置
void remove(): 删除迭代器对象当前指向的元素
3.2增强for
- 它是JDK5之后出现的,其内部原理是一个Iterator迭代器
- 实现Iterable接口的类才可以使用迭代器和增强for
- 简化数组和Collection集合的遍历
for(集合/数组中元素的数据类型 变量名 : 集合/数组名) {
// 已经将当前遍历到的元素封装到变量中了,直接使用变量即可}
集合名.for在idea中自动生成
4.List
4.1概述
- 有序(存取顺序)集合
- 用户可以精确控制列表中每个元素的插入位置。可以通过控制整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
4.2特点
- 存取有序
- 可以重复
- 有索引
4.3特有方法
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
4.4List集合子类的特点
ArrayList:底层是数组结构实现,查询快、增删慢
LinkedList:底层是链表结构实现,查询慢、增删快
5.LinkedList
特有方法
public void addFirst(E e) | 在该列表开头插入指定的元素 |
public void addLast(E e) | 将指定的元素追加到此列表的末尾 |
public E getFirst() | 返回此列表中的第一个元素 |
public E getLast() | 返回此列表中的最后一个元素 |
public E removeFirst() | 从此列表中删除并返回第一个元素 |
public E removeLast() | 从此列表中删除并返回最后一个元素 |
6.Set
特点:
- 可以去除重复
- 存取顺序不一致
- 没有带索引的方法,所以带索引的遍历方法都不能用
7.TreeSet
7.1集合特点
- 不包含重复元素的集合
- 没有带索引的方法
- 可以将元素按照规则进行排序
- 底层是红黑树
7.3排序
7.3.1自然排序Comparable
- 使用空参构造创建TreeSet集合
- 自定义的Student类里实现Comparable接口,泛型要和实现接口类名相同
- 重写里面的compareTo方法
public class Student implements Comparable<Student> {
…
@override
public int compareTo(Student o){
//按照年龄升序排列 第一个参数是将要存入集合的元素 第二个参数是集合里原有的元素
int result = this.age - o.age;
result = result == 0 ? this.name.compareTo(o.name) : result;
return result;
}
}
原理:
如果返回值为负数,表示当前存入的元素是较小值,存左边;
如果返回值为0,表示当前存入的元素跟集合中的元素重复了,不存;
如果返回值为整数,表示当前存入的元素是较大值,存右边。
7.3.2比较器排序Comparator的使用
- TreeSet的带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是让集合构造方法接收Comparator的实现对象,重写compare(T o1,T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
TreeSet(Comparator<? super E> comparator)
例如:
TreeSet<Teacher> ts = new TreeSet<>(new Comparator<Teacher>() {
@override
public int compare(Teacher o1, Teacher o2) {
//o1表示现在要存入的那个元素
//o2表示已经存入到集合中的元素
int result = o1.getAge() - o2.getAge();
result = result == 0 ? o1.getName().compareTo(o2.getName()) : result;
return result;
}
});
7.3.3两种比较方式的区别
- 自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序(小左大右)
- 比较器排序:创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
- 默认自然排序,有需求考虑比较器排序
- 后面都接泛型与比较类名一致
8.HashSet
8.1概述
- 底层数据结构是哈希表
- 存取无序
- 元素不重复
- 没有带索引的方法,带索引的遍历方法都不能用
8.2哈希值(哈希码值)
JDK根据对象的地址值或者属性值,计算出来的int整数
获取对象的哈希值:public int hashCode{}:根据对象的地址值计算出来的
特点:
- 如果没有重写hashCode方法,那么是根据对象的地址值计算出来的哈希值;同一个对象多次调用hashCode方法返回的哈希值是相同的,不同对象的哈希值是不一样的
- 如果重写了hashCode方法,一般都是通过对象的属性值计算出来的哈希值,如果不同的对象的属性值是一样的,那么计算出来的哈希值也是一样的。
8.3哈希表
JDK8以前,底层采用数组+链表实现
JDK8以后,节点数少于等于8个,数组+链表;节点数大于8个,数组+红黑树
1.7原理:
- 创建一个默认长度16,默认加载因子(负载因子)为0.75的数组(加载因子决定数组在什么时候进行x2的扩容,数组名是table)
- 根据元素的哈希值和数组的长度计算出应存入的位置
- 判断当前位置是否为null,如果为null,直接存入,如果不为null,表示当前位置有元素,比较它们的属性值(equals方法);如果不相等,将新元素存入,老元素通过链表挂在新元素下面(头插法),如果相等,不存。
1.8原理:
当挂在下面的元素过多(尾插法),不利于查询与修改,当元素超过8时,会自动转为红黑树。
8.4总结
HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法。
9.Map
9.1概念
- Interface Map<K,V>:K是键的数据类型;V是值的数据类型
- 键不能重复,值可以重复
- 键和值是一一对应,每一个键只能找到自己对应的值
- (键+值)这个整体成为“键值对”或“键值对对象”,Java中叫“Entry对象”
9.2基本功能
V put(K key,V value) | 添加元素 |
V remove(Object key) | 根据键删除键值对元素 |
void clear() | 移除所有的键值对元素 |
boolean containsKey(Object key) | 判断集合是否包含指定的键 |
boolean containsValue(Object value) | 判断集合是否包含指定的值 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是说集合中键值对的个数 |
如果要添加的键不存在,那么会把键值对都添加到集合中;如果要添加的键是存在的,那么会覆盖原先的值,并把原先的值当做返回值进行返回。
删除的返回值也是已删除的值。
9.3遍历
9.3.1通过键集合的键获取值
Set<K> keySet() | 获取所有键的集合 |
V get(Object key) | 根据键获取值 |
public class Test1 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a", "value1");
map.put("b", "value2");
map.put("c", "value3");
for(String s : map.keySet()){
System.out.println("key是"+s+"____value是"+map.get(s));
}
}
}
9.3.2通过键值对对象集合获得键和值
Set<Map.Entry<K,V>> entrySet() | 获取所有键值对对象的集合 |
K getKey() | 获得键 |
V getValue() | 获得值 |
public class Test1 {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("a", "value1");
map.put("b", "value2");
map.put("c", "value3");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
}
}
10.HashMap
map.put(" "," ")
特点:
- 底层是哈希表结构
- 依赖hashCode方法和equals方法保证键的唯一
- 键要存储自定义对象,要重写hashCode和equals方法;值不用
10.1遍历
迭代器、forEach方法
hm.forEach(lambda表达式)
hm.forEach(
(String key , String value)->{
}
);
11.TreeMap
排序的时候只关心键不关心值
- TreeMap底层是红黑树
- 依赖自然排序或者比较器排序,对键进行排序
- 如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象的时候给出比较器排序规则。
12.可变参数
形参的个数是可以变化的
public static int sum (int...a)变量实际就是
一个数组,多个参数,可变参数要放在最后
12.1创建不可变集合
- 该集合不能添加、删除、修改
- 可以结合集合的带参构造,实现集合的批量添加
- 在Map接口中,有一个ofEntries方法提高代码的阅读性:把键值对封装成一个Entry对象,再把这个Entry对象添加到集合当中
static<E> List<E> of(E...elements) | 创建一个具有指定元素的List集合对象 |
static<E> Set<E> of(E...elements) | 创建一个具有指定元素的Set合对象 |
static<E> Map<E> of(E...elements) | 创建一个具有指定元素的Map集合对象 |
public static void method3(){
Map<String,String> map = Map.ofEntries(
Map.entry("zhangsan","江苏"),
Map.entry("lisi","北京"),
);
sout(map)
}