集合框架&泛型
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变。
![image-20210125170210612](https://gitee.com/Ykahn/myblog/raw/master/img/image-20210125170210612.png)
一、Collection(单列集合)
创建Collection集合对象
-
多态的方式
-
具体实现类ArrayList
-
常用方法:
- add(E e) 添加元素
- remove(Object o) 从集合中移除指定元素
- clear() 清楚集合中元素
- contains()判断集合中是否存在指定元素
- isEmpty() 判断集合是否为空
- size() 集合长度(集合中元素个数)
Iterator(迭代器) :
-
构造方法:Iterator it =c.iterator
-
常用方法
- String s = it.next(); 获取元素
- hasNext() 判断迭代中是否还有元素
Iterator<String> it = array.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s); }
并发修改异常(ConcurrentModificationException):
- 使用迭代器Iterator获取元素时,不能进行add操作,否则会在运行next方法时出现“并发修改异常”)
- modCount != expectedModCount(实际修改次数不等于预期修改次数)
Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = it.next(); //并发修改异常 if (s.equals("风清扬")) { array.add("岳不群"); } System.out.println(s); } System.out.println("==================="); for (String x : array) { //增强型for循环也会报并发修改异常 if (x.equals("风清扬")) { array.add("岳不群"); } System.out.println(x); } System.out.println("==================="); for (int i = 0; i < array.size(); i++) { String x = array.get(i); //普通for循环修改时不报错 if (x.equals("风清扬")) { array.add("岳不群"); } System.out.println(x); }
- **三种遍历方式:**除了使用迭代器外,还可以使用
for循环
,增强型for循环
遍历集合
- 迭代器——集合特有的遍历方式
- 普通for循环——带有索引的遍历方式
- 增强型for循环 (内部原理是一个Iterator迭代器)——最方便的遍历方式
1、List(有序可重复)
可以通过整数索引和搜索 元素
1.ArrayList(常用)(顺序存储)
ArrayList:
- List接口的可调整大小的数组实现
- :是一种特殊的数据类型,泛型。
-
ArrayList构造方法
-
ArrayList、ArrayList
-
ArrayList array = new ArrayList<>();
-
-
常用方法
- add()、add(E e)
- remove(Object o) 、remove(int index)
- set、get
- size
- contains 包含
- 遍历:使用增强for循环,或Iterator迭代器
2.LinkedList(常用)(链式存储)
- 特有功能
- addFirst()、getFirst()、removeFirst()
- addLast()、getLast()、removeLast()
ListIterator**(迭代器)😗* (较少使用,了解即可)
- 列表的迭代器,允许程序员在***任一方向***上遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。
- 构造方法:ListIterator it =list.listIterator
- 常用方法(以下方法相对于next&hasNext)
- previous() & hasPrevious()
- ListIterator中运行 add() 与Iterator不同,不会 报并发修改异常 ,且实现的是插入(而非增加)
…、Vector、Stack
2、Set(无序不可重复)
- 不包含重复元素的集合,没有索引方法,不能使用普通for循环遍历
1.HashSet(常用)
- 哈希值
- 默认情况下,不同对象的哈希值是不相同的,同一个对象多次调用hashCode()得到值相同
- 通过方法重写,可以实现不同对象的哈希值相同
- 哈希表保证元素唯一
- 添加元素顺序与遍历输出顺序不一致
LinkedHashSet(链表实现的HashSet)
添加元素顺序与遍历输出顺序一致
哈希表保证元素唯一,链表保证存取顺序一致
2.TreeSet
-
其元素有序,可以根据自然排序,也可以通过比较器排序;
-
TreeSet() 无参数时,自然排序
-
TreeSet(Comparator<> comparator) 根据指定的比较器进行排序
自然排序Comparable的使用
- 要使用自然排序时,该类必须实现其接口(即使用TreeSet时若使用无参构造,所在类必须实现),重写方法compareTo。
比较器排序Comparator的使用
可以使用匿名内部类实现 new Comparator(){}
重写compare(T o1, T o2)
有多项需要去重时: 需要重写类中的equals()方法
二、Map(双列集合)
-
Map集合概述
- interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
- 键值对映射关系
- 一个键对应一个值
- 键不能重复,值可以重复
- 元素存取无序
-
Map集合的基本使用
public class MapDemo01 {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key, V value) 将指定的值与该映射中的指定键相关联
map.put("itheima001","林青霞");
map.put("itheima002","张曼玉");
map.put("itheima003","王祖贤");
map.put("itheima003","柳岩");
//输出集合对象
System.out.println(map);
}
}
//HashMap 哈希表保证键K唯一
-
常用方法(基本功能)
- put(K key,V value) 添加元素
- remove(Object key) 根据键删除键值对元素
- clear() 移除所有的键值对元素
- containsKey(Object key) 判断集合是否包含指定的键
- containsValue(Object value) 判断集合是否包含指定的值
- isEmpty() 判断集合是否为空
- size() 集合的长度
-
获取功能
- V get(Object key) 根据键获取值
- Set keySet() 获取所有键的集合
- Collection values()获取所有值的集合
- Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
-
遍历方式(把 Map的键、值看作夫妻对)
- 方式1:先获取所有丈夫,然后根据丈夫找妻子
- 获取所有键的集合 keySet()
- 遍历键的集合 增强for循环
- 根据键获取值 get()
- 方式2:找到所有结婚证,根据结婚证找出丈夫和妻子
- 获取所有键值对对象的集合 Set<Map.Entry<K,V>> entrySet()
- 遍历键值对对象的集合,得到每一个键值对对象 增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值 使用getKey() getValue()
- 方式1:先获取所有丈夫,然后根据丈夫找妻子
1.HashMap
- 重点,面试高频问点
- HashMap
- jdk1.7:数组+链表
- jdk1.8:hash=数组+链表+红黑树
集合嵌套:
- ArrayList嵌套HashMap
- HashMap嵌套ArrayList
2.TreeMap
类似 TreeSet,默认对键进行排序
三、泛型<>
…待补充完善
1、泛型概述
JDK5特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
- 它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
参数化类型:将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
-
泛型定义格式
- <类型>:指定一种类型的格式。这里的类型可以看成是形参
- <类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
-
泛型的好处:
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换(约束,避免类型转换之间的问题)
2、泛型类、泛型方法、泛型接口
T 类型 t变量
1.泛型类
修饰符 class 类名 { }
2.泛型方法
修饰符 返回值类型 方法名(T t) { }
3.泛型接口
修饰符 interface 接口名 { }
3、类型通配符
类型通配符
类型通配符的作用:
为了表示各种泛型List的父类,可以使用类型通配符
类型通配符的分类
类型通配符
- List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
- 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
类型通配符上限:List<? extends 类型>
- List<? extends Number>:它表示的类型是Number或者其子类型
类型通配符下限:List<? super 类型>
- List<? super Number>:它表示的类型是Number或者其父类型
4、可变参数
可变参数(不定项参数,由数组实现)
- JDK1.5开始,java支持同类型的可变参数给一个方法
- 在指定参数类型后加一个省略号(…)
- 必须放在最后一个参数,且一个方法中只支持一个可变参数
- 格式:
- 修饰符 返回值类型 方法名(数据类型… 变量名) { }
注:在学习方法中提到过
可变参数的使用:
Arrays工具类中有一个静态方法:
- public static List asList(T… a):返回由指定数组支持的固定大小的列表
- 返回的集合不能做增删操作,可以做修改操作
List接口中有一个静态方法:
- public static List of(E… elements):返回包含任意数量元素的不可变列表
- 返回的集合不能做增删改操作
Set接口中有一个静态方法:
public static Set of(E… elements) :返回一个包含任意数量元素的不可变集合
在给元素的时候,不能给重复的元素 返回的集合不能做增删操作,没有修改的方法
四、Collections工具类
-
Collections类的作用
是针对集合操作的工具类
-
Collections类常用方法
- public static void sort(List list) 将指定的列表按升序排序
- public static void reverse(List<?> list) 反转指定列表中元素的顺序
- public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
…待补充完善
拓展:数据结构
…待补充
1、栈和队列
1.栈(stack)
-
FILO:先进后出
-
进栈/出栈:
2.队列(queue)
-
FIFO:先进先出
-
进队/出队:
2、数组和链表
1.数组
- 查询速度快
- 插入/删除慢
2.链表
- 插入/删除快
- 查询速度慢
3、哈希表
集合框架&泛型
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变。
![image-20210125170210612](https://gitee.com/Ykahn/myblog/raw/master/img/image-20210125170210612.png)
一、Collection(单列集合)
创建Collection集合对象
-
多态的方式
-
具体实现类ArrayList
-
常用方法:
- add(E e) 添加元素
- remove(Object o) 从集合中移除指定元素
- clear() 清楚集合中元素
- contains()判断集合中是否存在指定元素
- isEmpty() 判断集合是否为空
- size() 集合长度(集合中元素个数)
Iterator(迭代器) :
-
构造方法:Iterator it =c.iterator
-
常用方法
- String s = it.next(); 获取元素
- hasNext() 判断迭代中是否还有元素
Iterator<String> it = array.iterator(); while (it.hasNext()){ String s = it.next(); System.out.println(s); }
并发修改异常(ConcurrentModificationException):
- 使用迭代器Iterator获取元素时,不能进行add操作,否则会在运行next方法时出现“并发修改异常”)
- modCount != expectedModCount(实际修改次数不等于预期修改次数)
Iterator<String> it = array.iterator(); while (it.hasNext()) { String s = it.next(); //并发修改异常 if (s.equals("风清扬")) { array.add("岳不群"); } System.out.println(s); } System.out.println("==================="); for (String x : array) { //增强型for循环也会报并发修改异常 if (x.equals("风清扬")) { array.add("岳不群"); } System.out.println(x); } System.out.println("==================="); for (int i = 0; i < array.size(); i++) { String x = array.get(i); //普通for循环修改时不报错 if (x.equals("风清扬")) { array.add("岳不群"); } System.out.println(x); }
- **三种遍历方式:**除了使用迭代器外,还可以使用
for循环
,增强型for循环
遍历集合
- 迭代器——集合特有的遍历方式
- 普通for循环——带有索引的遍历方式
- 增强型for循环 (内部原理是一个Iterator迭代器)——最方便的遍历方式
1、List(有序可重复)
可以通过整数索引和搜索 元素
1.ArrayList(常用)(顺序存储)
ArrayList:
- List接口的可调整大小的数组实现
- :是一种特殊的数据类型,泛型。
-
ArrayList构造方法
-
ArrayList、ArrayList
-
ArrayList array = new ArrayList<>();
-
-
常用方法
- add()、add(E e)
- remove(Object o) 、remove(int index)
- set、get
- size
- contains 包含
- 遍历:使用增强for循环,或Iterator迭代器
2.LinkedList(常用)(链式存储)
- 特有功能
- addFirst()、getFirst()、removeFirst()
- addLast()、getLast()、removeLast()
ListIterator**(迭代器)😗* (较少使用,了解即可)
- 列表的迭代器,允许程序员在***任一方向***上遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。
- 构造方法:ListIterator it =list.listIterator
- 常用方法(以下方法相对于next&hasNext)
- previous() & hasPrevious()
- ListIterator中运行 add() 与Iterator不同,不会 报并发修改异常 ,且实现的是插入(而非增加)
…、Vector、Stack
2、Set(无序不可重复)
- 不包含重复元素的集合,没有索引方法,不能使用普通for循环遍历
1.HashSet(常用)
- 哈希值
- 默认情况下,不同对象的哈希值是不相同的,同一个对象多次调用hashCode()得到值相同
- 通过方法重写,可以实现不同对象的哈希值相同
- 哈希表保证元素唯一
- 添加元素顺序与遍历输出顺序不一致
LinkedHashSet(链表实现的HashSet)
添加元素顺序与遍历输出顺序一致
哈希表保证元素唯一,链表保证存取顺序一致
2.TreeSet
-
其元素有序,可以根据自然排序,也可以通过比较器排序;
-
TreeSet() 无参数时,自然排序
-
TreeSet(Comparator<> comparator) 根据指定的比较器进行排序
自然排序Comparable的使用
- 要使用自然排序时,该类必须实现其接口(即使用TreeSet时若使用无参构造,所在类必须实现),重写方法compareTo。
比较器排序Comparator的使用
可以使用匿名内部类实现 new Comparator(){}
重写compare(T o1, T o2)
有多项需要去重时: 需要重写类中的equals()方法
二、Map(双列集合)
-
Map集合概述
- interface Map<K,V> K:键的类型;V:值的类型
-
Map集合的特点
- 键值对映射关系
- 一个键对应一个值
- 键不能重复,值可以重复
- 元素存取无序
-
Map集合的基本使用
public class MapDemo01 {
public static void main(String[] args) {
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key, V value) 将指定的值与该映射中的指定键相关联
map.put("itheima001","林青霞");
map.put("itheima002","张曼玉");
map.put("itheima003","王祖贤");
map.put("itheima003","柳岩");
//输出集合对象
System.out.println(map);
}
}
//HashMap 哈希表保证键K唯一
-
常用方法(基本功能)
- put(K key,V value) 添加元素
- remove(Object key) 根据键删除键值对元素
- clear() 移除所有的键值对元素
- containsKey(Object key) 判断集合是否包含指定的键
- containsValue(Object value) 判断集合是否包含指定的值
- isEmpty() 判断集合是否为空
- size() 集合的长度
-
获取功能
- V get(Object key) 根据键获取值
- Set keySet() 获取所有键的集合
- Collection values()获取所有值的集合
- Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
-
遍历方式(把 Map的键、值看作夫妻对)
- 方式1:先获取所有丈夫,然后根据丈夫找妻子
- 获取所有键的集合 keySet()
- 遍历键的集合 增强for循环
- 根据键获取值 get()
- 方式2:找到所有结婚证,根据结婚证找出丈夫和妻子
- 获取所有键值对对象的集合 Set<Map.Entry<K,V>> entrySet()
- 遍历键值对对象的集合,得到每一个键值对对象 增强for实现,得到每一个Map.Entry
- 根据键值对对象获取键和值 使用getKey() getValue()
- 方式1:先获取所有丈夫,然后根据丈夫找妻子
1.HashMap
- 重点,面试高频问点
- HashMap
- jdk1.7:数组+链表
- jdk1.8:hash=数组+链表+红黑树
集合嵌套:
- ArrayList嵌套HashMap
- HashMap嵌套ArrayList
2.TreeMap
类似 TreeSet,默认对键进行排序
三、泛型<>
…待补充完善
1、泛型概述
JDK5特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型
- 它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
参数化类型:将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型。
这种参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
-
泛型定义格式
- <类型>:指定一种类型的格式。这里的类型可以看成是形参
- <类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
-
泛型的好处:
- 把运行时期的问题提前到了编译期间
- 避免了强制类型转换(约束,避免类型转换之间的问题)
2、泛型类、泛型方法、泛型接口
T 类型 t变量
1.泛型类
修饰符 class 类名 { }
2.泛型方法
修饰符 返回值类型 方法名(T t) { }
3.泛型接口
修饰符 interface 接口名 { }
3、类型通配符
类型通配符
类型通配符的作用:
为了表示各种泛型List的父类,可以使用类型通配符
类型通配符的分类
类型通配符
- List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
- 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
类型通配符上限:List<? extends 类型>
- List<? extends Number>:它表示的类型是Number或者其子类型
类型通配符下限:List<? super 类型>
- List<? super Number>:它表示的类型是Number或者其父类型
4、可变参数
可变参数(不定项参数,由数组实现)
- JDK1.5开始,java支持同类型的可变参数给一个方法
- 在指定参数类型后加一个省略号(…)
- 必须放在最后一个参数,且一个方法中只支持一个可变参数
- 格式:
- 修饰符 返回值类型 方法名(数据类型… 变量名) { }
注:在学习方法中提到过
可变参数的使用:
Arrays工具类中有一个静态方法:
- public static List asList(T… a):返回由指定数组支持的固定大小的列表
- 返回的集合不能做增删操作,可以做修改操作
List接口中有一个静态方法:
- public static List of(E… elements):返回包含任意数量元素的不可变列表
- 返回的集合不能做增删改操作
Set接口中有一个静态方法:
public static Set of(E… elements) :返回一个包含任意数量元素的不可变集合
在给元素的时候,不能给重复的元素 返回的集合不能做增删操作,没有修改的方法
四、Collections工具类
-
Collections类的作用
是针对集合操作的工具类
-
Collections类常用方法
- public static void sort(List list) 将指定的列表按升序排序
- public static void reverse(List<?> list) 反转指定列表中元素的顺序
- public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
…待补充完善
拓展:数据结构
…待补充
1、栈和队列
1.栈(stack)
-
FILO:先进后出
-
进栈/出栈:
2.队列(queue)
-
FIFO:先进先出
-
进队/出队:
2、数组和链表
1.数组
- 查询速度快
- 插入/删除慢
2.链表
- 插入/删除快
- 查询速度慢