全面了解Java集合

简介: 追根溯源全面上手集合(建议反复观看)

前言

设计集合的作者真的是太伟大了,就拿一个简简单单的add()方法,背后的动作在深入了解之后你会强烈感受到了人类的智慧

一.集合VS数组

数组完成定义并启动后,类型确定,长度固定。适合元素的个数和类型确定的业务情景,不适合进行CRUD的操作,就像一个铁盒子放的东西数量是固定的
在这里插入图片描述

集合的大小不固定,启动后可以动态改变,因此适合做数据个数不确定且需要增删元素的场景,集合就像一个气球,想变大就吹气!
在这里插入图片描述**

二.集合体系特点

**Collection单列集合:每个元素(数据)只包含一个值
==注==:set接口的实现子类也有存在两个值的(键值对[K-V]只不过其中的V是一个静态常量PRESENT)实际起作用的还是对象K(key)所以就把他也算作单列了
Map双列集合:每个元素包含两个值(键值对k-v)**
在这里插入图片描述

三.Collection单列集合

Collection这个接口有很多实现类,每一个类也包含了很多内部方法,主流的是List、Set这两个系列
以下是几个常用的实现类
在这里插入图片描述

性能对比(🏁)

**ArrayList:数据结构是数组,查询快,增删慢,线程不安全,效率高,存取顺序一致可重复
LinkedList:数据结构是链表,查询慢,增删快,线程不安全,效率高,存取顺序一致可重复
Vector(很少用):数据结构是数组,查询快,增删慢,线程安全,效率低,存取顺序一致可重复
HashSet:数据结构是哈希表,查询快,增删慢,线程不安全,效率高,存取顺序不一致不可重复
LinkedHashSet:数据结构是链表+哈希表,查询快,增删慢,线程不安全,效率高,存取顺序一致不可重复
TreeSet:数据结构是二叉树,查询快,增删慢,线程不安全,效率高,存取顺序不一致不可重复**

1.List系列常用API

List集合类中元素添加顺序和取出顺序一致、且可重复,List集合中的每个元素都有其对应的顺序索引
List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素
以ArrayList为例演示一下List接口实现类的常用方法

**1.add(E e):在集合末尾新增一个元素
2.add(int index, E element):在指定位置添加元素
3.get(int index):获取指定位置的元素
4.remove(int index) :删除指定位置的元素
5.remove(Object o): 删除指定元素
6.indexOf(Object o) :查询指定元素的位置 lastIndexOf也一样,只是从尾部开始遍历
7.set(int index, E element): 设置指定位置的元素值
8.retainAll(Collection<?> c) :求两个集合的交集
9.subList(int fromlndex, int tolndex) :获取【x,y)区间元素
10.set(int index, Object ele) :设置指定位置元素
11.indexOf(Object obj):返回元素在集合中首次出现的位置
12.lastIndexOf(Object obj):返回元素在当前集合中末次出现的位置**
........
  ArrayList col = new ArrayList();
  col.add("懒羊羊");  //添加单个元素
  col.add(100);  //col.add(new Integer(100))     
  col.remove("懒羊羊"); //删除指定元素
  col.remove(0); //删除第一个元素(索引)             
  System.out.println(col.size());  //获取元素个数
  System.out.println(col.isEmpty()); //看是否为空 
  col.clear();//清空
        
  ArrayList c1 = new ArrayList();
  c1.add("AA");
  col.addAll(c1); //把集合c1存进集合col
      
  ArrayList c2 = new ArrayList();
  c2.add("CC");
  c2.add("AA~");
  col.containsAll(c2); //查找col里是否有c2
  col.removeAll(c2);  //删除多个元素 删除col中的c2集合
  col returnlist=col.subList(0,2); //获取区间元素
  col.set(1, "喜羊羊");//设置指定位置元素
  col.indexOf("懒羊羊");//返回懒羊羊在集合中首次出现的位置
  col.lastIndexOf("懒羊羊");//返回懒羊羊在当前集合中末次出现的位置

==注==:每一个接口实现类的方法非常多,感兴趣可以自己去看看

2.Set系列常用API

和List系列集合一样,set系列集合也是Collection接口的实现类,所以用法和上述差不太多
==注==:set接口的实现类的对象(Set接口对象),不能存放重复的元素,可以添加一个null,set接口对象存放数据是无序(即添加的顺序和取出的顺序不一致)
内部方法大部分都一样,只不过不能使用索引来操作集合元素,因为set接口对象存放数据无序

   HashSet hs = new HashSet();
   hs.add(null);
   hs.add("懒羊羊");//添加单个元素
   hs.remove("懒羊羊"); //删除指定元素
   hs.remove(0); //删除第一个元素
   System.out.println(hs.size());  //获取元素个数
   System.out.println(hs.isEmpty()); //看是否为空 
   hs.clear();//清空

   HashSet c1 = new HashSet();
   c1.add("AA");
   hs.addAll(c1); //把集合c1存进集合hs

   HashSet c2 = new HashSet();
   c2.add("CC");
   c2.add("AA~");
   hs.containsAll(c2); //查找hs里是否有c2
   hs.removeAll(c2);  //删除多个元素 删除hs中的c2集合

四.Map双列集合

Map与Collection并列存在,用于保存具有映射关系的数据:Key-Value,Map接口也有很多实现类,HashMap较为典型,下图是一部分实现类
在这里插入图片描述
HashMap:数据结构是哈希表,查询快,线程不安全,无序不重复
LinkedHashMap:数据结构是哈希表+链表,查询快,线程不安全,有序不重复

1.Map系列常用API

Map 中的 key和 value可以是==任何引用类型的数据==,会封装到HashMap$Node对象中,Map中的key不允许重复,value可以重复
Map的key可以为null, value也可以为null,注意key为null, 只能有一个,value为null可以有多个一般用String类作为Map的key
注:key和 value 之间存在==单向一对一==关系,即通过指定的key总能找到对应的value

**1.put(key,value):通过k-v添加元素
2.replace(3, "小灰灰"):在指定元素key的数据替换为新的value
3.clear():清空元素
4.isEmpty():判断是否为空返回boolean类型
5.put(new Object(),"灰太狼"):k-v中的K可以存放对象
6.get(key):用于获取指定K的元素
7.remove(key):删除指定元素**
Map map = new HashMap();
map.put( "1","懒羊羊");//通过k-v添加元素
map.put( "2","慢羊羊");//k-v
map.put("1","沸羊羊");//当有相同的k,就等价于替换
map.put( "3","美羊羊");//k-v
map.put(null, null); //可添加null
map.put(null,"喜羊羊");//通过相同的null等价替换
map.replace(3, "小灰灰");//在指定元素key的数据替换为新的value
map.get(3);//获取k为3的元素
map.size();//获取集合大小
map.clear();//清空元素
map.isEmpty(); //判断是否为空返回boolean类型
map.put(new Object(),"灰太狼");  //k-v

五.集合的遍历方式

集合的遍历就是一个一个的把容器中的元素访问一遍

1.迭代器遍历(🏁)

迭代器在Java中的代表是Iterator,有时又称光标(cursor)是程序设计的软件设计模式,迭代器是集合的专用遍历方式
1.首先要获得迭代器:

Collection col = new ArrayList();
Iterator m= col.iterator(); //获得集合对象col的迭代器 m

2.其次遍历集合:

while (m.hasNext()) {//使用while循环遍历 判断是否还有数据
     Object obj =m.next(); //动态绑定 取决于运行类型(什么样的对象)
     System.out.println(obj);//打印集合中的元素
}

完成迭代器遍历集合
==注==:如果要在当前基础上再次遍历还需要重新获取一下迭代器

2.增强for循环遍历

增强for循环遍历的本质还是利用迭代器

Collection col = new ArrayList();
for (Object o : col) {
            System.out.println(o);
        }

3.Lambda表达式遍历

从JDK8开始产生的新技术Lambda表达式遍历,是一种==更简单,更直接==的遍历集合的方式

Collection col = new ArrayList();
col.forEach(s ->{
   System.out.println(s);
});

4.Map遍历特例

1.遍历Map时,可以通过Key来遍历,首先要做的是取出所有的key,然后通过key得到value
具体操作:Collection keys = map.keySet();然后通过迭代器,增强for循环进行遍历,因为存在.get(key)方法,所以遍历过程中可以通过此方法得到集合中的所有元素
可以使用Collection的遍历方法本质也==是多态的体现==
在这里插入图片描述

2.第二种方式通过values遍历
具体操作:Collection values = map.values();同样也可以使用迭代器,增强for循环
注:遍历集合取出的是value
本质也是values()方法实现了Set接口,Set接口继承了Collection接口(==体现多态性==
在这里插入图片描述
3.第三种则是通过EntrySet获取k-v的方式遍历
具体操作:

Collection es = map.entrySet();
for (object entry : es) {
      Map.Entry m = (Map.Entry) entry;//将entry转型成成Map.Entry才能使用下面两个方法 
    system.out.println(m.getKey() + "" + m.getValue());
}

也可以选择迭代器遍历

六.集合存储对象过程

1.ArrayList集合底层原理(🏳️‍🌈)

ArrayList底层是基于数组实现的:
根据索引定位元素快,增删需要做元素的移位操作。第一次创建集合并添加第一个元素的时候,在底层创建一个默认长度为10的数组。
通过ArrayList的内部方法.add()来解读源码:

1.当创建ArrayList对象时,如果使用的是无参构造器,首先创建空的elementData数组 在这里插入图片描述
在这里插入图片描述
2.执行add()向空数组扩容 在这里插入图片描述
这个方法里包含了很多动作它先通过ensureCapacityInternal()判断是否要扩容
在这里插入图片描述
再通过calculateCapacity()判断elementData是否为空数组,若是则返回10,并将空数组扩容至为空间为10 在这里插入图片描述

3.当执行的add操作大于当前容量(10)则与当前空间大小比较并执行grow()方法进行扩容 在这里插入图片描述
4.前面我们知道初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍,注意没有拷贝数祖前里面的元素都是null
在这里插入图片描述

2.LinkedList集合底层原理(🏳️‍🌈)

原码解读:

1.首先也是通过构造器创建一个大小为0的链表,并且头尾都指向null 在这里插入图片描述
2.当执行add()添加操作时调用linkLast()方法 在这里插入图片描述
使用linkLast()将新的节点加入到双向链表尾部,也就是last指向“1”这个节点
在这里插入图片描述
同理也使用Linkedfirst()让first指向“1”这个节点

最后完成了add(1)的操作 将1添加到双向链表中
在这里插入图片描述

感想

我真是好后悔没把数据结构学到位
写到这里:==懒羊羊寿命-2年==

相关文章
|
3月前
|
存储 安全 Java
常见 JAVA 集合面试题整理 自用版持续更新
这是一份详尽的Java集合面试题总结,涵盖ArrayList与LinkedList、HashMap与HashTable、HashSet与TreeSet的区别,以及ConcurrentHashMap的实现原理。内容从底层数据结构、性能特点到应用场景逐一剖析,并提供代码示例便于理解。此外,还介绍了如何遍历HashMap和HashTable。无论是初学者还是进阶开发者,都能从中受益。代码资源可从[链接](https://pan.quark.cn/s/14fcf913bae6)获取。
176 3
|
2月前
|
Oracle Java 关系型数据库
掌握Java Stream API:高效集合处理的利器
掌握Java Stream API:高效集合处理的利器
329 80
|
2月前
|
安全 Java API
Java 8 Stream API:高效集合处理的利器
Java 8 Stream API:高效集合处理的利器
221 83
|
5月前
|
消息中间件 算法 安全
JUC并发—1.Java集合包底层源码剖析
本文主要对JDK中的集合包源码进行了剖析。
|
2月前
|
并行计算 Java API
Java List 集合结合 Java 17 新特性与现代开发实践的深度解析及实战指南 Java List 集合
本文深入解析Java 17中List集合的现代用法,结合函数式编程、Stream API、密封类、模式匹配等新特性,通过实操案例讲解数据处理、并行计算、响应式编程等场景下的高级应用,帮助开发者提升集合操作效率与代码质量。
124 1
|
2月前
|
存储 缓存 NoSQL
java 集合入门基础理论的核心概念与实用长尾知识
本文介绍了Java集合框架的基础理论知识,包括单列集合(List、Set、Queue)和双列集合(Map)的特点及常用实现类(如ArrayList、HashSet、HashMap等)。详细讲解了集合的遍历方式(迭代器、增强for循环、Lambda表达式)和典型应用场景(如数据去重、键值存储等)。通过具体代码示例,帮助初学者理解集合框架的核心概念和实际应用,为Java编程中的数据存储与管理提供基础指导。
71 0
|
2月前
|
安全 Java API
Java 集合高级应用与实战技巧之高效运用方法及实战案例解析
本课程深入讲解Java集合的高级应用与实战技巧,涵盖Stream API、并行处理、Optional类、现代化Map操作、不可变集合、异步处理及高级排序等核心内容,结合丰富示例,助你掌握Java集合的高效运用,提升代码质量与开发效率。
181 0
|
2月前
|
存储 安全 Java
Java 学习路线 35 掌握 List 集合从入门到精通的 List 集合核心知识
本文详细解析Java中List集合的原理、常用实现类(如ArrayList、LinkedList)、核心方法及遍历方式,并结合数据去重、排序等实际应用场景,帮助开发者掌握List在不同业务场景下的高效使用,提升Java编程能力。
277 0
|
3月前
|
安全 Java API
Java最新技术(JDK 11+) 及以上 Java 最新技术之集合框架实操应用详解
本示例基于Java最新技术(JDK 11+),涵盖集合框架的核心功能,结合Java 8+特性(如Stream API、Lambda表达式)与并发编程最佳实践。内容包括:List操作(初始化、Lambda过滤、Stream处理)、Map操作(流式过滤、ConcurrentHashMap原子操作、并行流)、Set操作(TreeSet排序、CopyOnWriteArraySet并发安全)、Queue/Deque操作(优先队列、双端队列)以及高级聚合操作(集合转换、分组统计、平均值计算)。 [代码下载](https://pan.quark.cn/s/14fcf913bae6)
69 4