全面了解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月前
|
消息中间件 算法 安全
JUC并发—1.Java集合包底层源码剖析
本文主要对JDK中的集合包源码进行了剖析。
|
1月前
|
存储 安全 算法
Java 集合面试题 PDF 下载及高频考点解析
本文围绕Java集合面试题展开,详细解析了集合框架的基本概念、常见集合类的特点与应用场景。内容涵盖`ArrayList`与`LinkedList`的区别、`HashSet`与`TreeSet`的对比、`HashMap`与`ConcurrentHashMap`的线程安全性分析等。通过技术方案与应用实例,帮助读者深入理解集合类的特性和使用场景,提升解决实际开发问题的能力。文末附带资源链接,供进一步学习参考。
54 4
|
1月前
|
存储 安全 Java
现代应用场景中 Java 集合框架的核心技术与实践要点
本内容聚焦Java 17及最新技术趋势,通过实例解析Java集合框架的高级用法与性能优化。涵盖Record类简化数据模型、集合工厂方法创建不可变集合、HashMap初始容量调优、ConcurrentHashMap高效并发处理、Stream API复杂数据操作与并行流、TreeMap自定义排序等核心知识点。同时引入JMH微基准测试与VisualVM工具分析性能,总结现代集合框架最佳实践,如泛型使用、合适集合类型选择及线程安全策略。结合实际案例,助你深入掌握Java集合框架的高效应用与优化技巧。
64 4
|
1月前
|
存储 安全 Java
Java 集合面试题从数据结构到 HashMap 源码剖析详解及长尾考点梳理
本文深入解析Java集合框架,涵盖基础概念、常见集合类型及HashMap的底层数据结构与源码实现。从Collection、Map到Iterator接口,逐一剖析其特性与应用场景。重点解读HashMap在JDK1.7与1.8中的数据结构演变,包括数组+链表+红黑树优化,以及put方法和扩容机制的实现细节。结合订单管理与用户权限管理等实际案例,展示集合框架的应用价值,助你全面掌握相关知识,轻松应对面试与开发需求。
107 3
|
7月前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
114 3
|
3月前
|
Java
Java LinkedList集合的深度剖析
总的来说,我希望像说故事一样讲解Java LinkedList集合的使用和实现原理,让有些许枯燥的编程知识变得趣味盎然。在这个“公交车”故事中,你不仅熟悉了LinkedList集合的实现和使用,而且还更深入地理解了数据结构中的链表。链表可能会因为插入和删除的便利性而被选用,虽然它的查找效率并不高,但是在很多场景中仍然十分有效。这就像公交车,虽然它速度不快,但却是城市出行的重要工具。
73 8
|
9月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
103 3
|
3月前
|
存储 安全 Java
Java 集合框架详解:系统化分析与高级应用
本文深入解析Java集合框架,涵盖List、Set、Map等核心接口及其常见实现类,如ArrayList、HashSet、HashMap等。通过对比不同集合类型的特性与应用场景,帮助开发者选择最优方案。同时介绍Iterator迭代机制、Collections工具类及Stream API等高级功能,提升代码效率与可维护性。适合初学者与进阶开发者系统学习与实践。
95 0
|
4月前
|
Java
java常见的集合类有哪些
Map接口和Collection接口是所有集合框架的父接口: 1. Collection接口的子接口包括:Set接口和List接口 2. Map接口的实现类主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及 Properties等 3. Set接口的实现类主要有:HashSet、TreeSet、LinkedHashSet等 4. List接口的实现类主要有:ArrayList、LinkedList、Stack以及Vector等
|
7月前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
117 5