文章目录
一、认识集合框架
集合的主要作用是存储数据。之前已经接触过 数组 和 ArrayList
数据库也能存储数据:
- 数据库的数据 ——>表 ——> 文件保存在硬盘中 ===文件不丢失
1、概念
- 所有数据的存储,至少需要 GUI界面 / 算法 /存储介质
- GUI——算法——>存储介质
- 为了方便存储数据,Java自带了各种数据的存储结构
- Java自带的各种数据的存储结构 ——就是集合框架 (面试常考)
- 《数据结构与算法》 algorithm :和语言没有关系
- Java中的数据结构 —— 集合框架
2、分类
一般分为:List结构 , Map结构 , Set结构
- List结构 :列表结构 ——> 所有数据一一对应
- 存储一组不唯一,**有序(插入顺序)**的对象。
- Map结构:映射结构 ——> 键值对 key/value
- 存储一组键值对象,提供key(键)到value(值)的映射。
- Set结构:集合结构 ——> 没有顺序的存储数据
- 存储一组唯一,无序的对象。(注意:集合的数据不能重复
- RT:
二、List 列表结构
概念:前面提到,List存储的是 一组不唯一 ,有序的数据
-
根据具体的实现方式,分成不同算法:
- 数据结构、链表结构
-
在实际操作中,提供给程序员一套通用的操作方法:
-
数据结构 ——抽象成——> 接口
-
List存在很多不同的接口,但是都有通用的方法:
-
存 add
-
取 get
-
删除 remove
-
长度 size
-
以及遍历
-
-
-
举个例子
psvm{ List list1; // 注意导包是导入 utils目录下的 // 数组型的List List<String> list2 = new ArrayList<>(); // 右边的<>可以不写数据类型 // 链表型的List List<String> list3 = new LinkedList<>(); // 存 取 删 长度 略 // 遍历1: for循环通过下标进行遍历 for (int i = 0 ; i < list2.size() :i++){ sout(list2.get(i)); } // 遍历2: for each 通过内容遍历 for (String val : list2){ sout(val); // 直接获得里面的内容,可以减少一个i的变量 } // 遍历3: java集合框架内部 提供的 : 迭代器iterator // 迭代器的接口 Iterator Iterator<String> iterator = list2.iterator(); while(iterator.hasNext()){ // 先判断是否有下一个值 String val = iterator.next(); // 再获得内容 // next()做了两件事:先移到下一个位置,后取值 sout(val); } }
-
列表数组的分类:
- ArrayList 列表
- LinkedList 链表
- Vector 线程安全 但是速度慢,已经淘汰
- Stack Queue 堆栈等
三、Set集合
*前面提到:*集合是一种无序结构,值是唯一,不能重复
-
按规则分类
- Hash算法 HashSet :哈希算法 最常用的
- Tree算法 TreeSet
-
接口 ——
Set
,也有通用的操作- 存:add
取:get——因为set是无序的,所以无法单独取出数据- 删除:remove
- 长度:size
- 遍历
-
举个例子
public static void main(String[] args) { Set<String> set1 = new HashSet<>(); Set<String> set2 = new TreeSet<>(); set1.add("老王"); set1.add("老谢"); set1.add("老谢"); // 存储一个重复的String set1.add("老A"); set1.add("老B"); set1.add("老C"); System.out.println(set1.size()); // 求这个集合的长度, // 遍历 只能是 foreach 和 迭代器遍历 // 遍历1: for each 通过内容遍历 for (String val : set1){ System.out.println(val); // 遍历的顺序是按照hash算法规则遍历的 } // 遍历2: 迭代器iterator Iterator<String> iterator = set1.iterator(); while(iterator.hasNext()){ // 先判断是否有下一个值 String val = iterator.next(); // 再获得内容 // next()做了两件事:先移到下一个位置,后取值 System.out.println(val); } } //输出结果 5 老谢 老王 老C 老B 老A ------------- 老谢 老王 老C 老B 老A
- 注意集合中的内容是不重复的,插入重复的数据,并不会增加长度
- 大厂面试可能会问——hash算法规则
四、Map映射结构
*前面提到,*映射结构是键值对的结构
-
key的存储结构:也是按set的方式存储。
- 根据这个存储方法分类也可以分为Hash 和 Tree
- Hash —— HashMap
- Tree —— TreeMap
- 根据这个存储方法分类也可以分为Hash 和 Tree
-
map接口的通用操作:
-
map接口的声明方法
Map<Object1 , Object2> map = new HashMap<>(); // 需要有两个对象
-
存 :
put(key , value)
-
取:
get(key)
-
删除:
-
长度:size
-
遍历:map 的遍历比较特殊,可以选择遍历key,遍历value,或key/value一起遍历
- 遍历key :涉及到技术点:
keySet()
——获取这个map的键集合 - 遍历value:涉及到技术点:values() —— 获得这个map 的值Collection
- 缺点:无法获得key
- 整体遍历:用到的是内部接口
Map.Entry<>
这个接口可以存储key和value - 也可以用迭代器进行整体遍历:
- 遍历key :涉及到技术点:
-
-
举个例子
public static void main(String[] args) { Map<String , String> map = new HashMap<>(0); map.put("001" , "老王"); map.put("002" , "老谢"); map.put("003" , "老A"); map.put("004" , "老B"); map.put("005" , "老D"); System.out.println("列表长度为:"+map.size()); // 长度 map.put("005" , "老F"); // 添加一个重复的key 发现长度仍然是5 System.out.println("新增老F后 列表长度为:"+map.size()); // 长度 System.out.println("005的值为:"+map.get("005")); // 查看重复key的value是多少 System.out.println("通过key遍历map===="); // 通过 foreach 遍历key 输出key和value for (String key : map.keySet()) { System.out.println(key + "\t " +map.get(key)); } System.out.println("通过value遍历map===="); // 通过foreach 遍历value 输出value for (String val: map.values() ) { System.out.println(val); } System.out.println("通过key/value整体 遍历map ====="); // 需要一个对象表示 key/value整体 Entry类型 for (Map.Entry<String , String> entry : map.entrySet()) { System.out.println(entry.getKey() + "\t" + entry.getValue()); } System.out.println("迭代器+通过key/value整体 遍历map ====="); Iterator<Map.Entry<String , String>> iterator = map.entrySet().iterator(); // 建立迭代器,存储的是entry对象 while (iterator.hasNext()){ Map.Entry<String , String> entry = iterator.next(); // 注意先将entry对象存储在一个临时的对象里 System.out.println(entry.getKey() + "\t " + entry.getValue()); } } // 输出结果 列表长度为:5 新增老F后 列表长度为:5 005的值为:老F 通过key遍历map==== 001 老王 002 老谢 003 老A 004 老B 005 老F 通过value遍历map==== 老王 老谢 老A 老B 老F 通过key/value整体 遍历map ===== 001 老王 002 老谢 003 老A 004 老B 005 老F
五、集合框架图
-
类关系图
- 实线——继承关系
- 虚线+空心箭头 —— 接口的实现关系
- 虚线+实心箭头 —— 接口之间的关系
-
集合框架图
-
注意:右下角还有工具类:
Utilities
- 包含Collections Arrays
- 包含了集合的拷贝、排序、转换(集合和数组之间的转换)等操作
- 查询帮助文档
⭐️面试问题:ArrayList 和 LinkedList 的区别
-
存储空间的区别:数组(空间是连续的)、链表结构(空间不是连续的
-
增删改查的区别
-
查询的区别:
-
简单理解,数组可以根据下标快速查询到对应的数据,链表必须一个个按顺序查询
-
所以:数组查询比较快,链表查询比较慢
-
-
插入的区别
- 数组的插入会导致其他数据的下标一起下移
- 链表的插入只要在两者之间新建立连接即可
- 所以,链表的插入比较快,数组比较慢
-
删除和插入同理,也是链表删除比较快
-
⭐️面试问题:ArrayList 和 数组 的区别(为什么ArrayList可以存储不限长度的数组?)
- ArrayList 是对数组进行封装,默认定义一个长度为n的数组
- 查看源码可以发现 n为10
- 当长度不够时,就会创建新的数组,把旧数组的数组拷贝到新数组里