关于JAVA集合你了解多少?

1、集合框架的由来

在编程设计中,数据结构(算法)担任着不可或缺的角色,在JAVA语言中,JAVA的设计者将数据结构进行了封装,这个封装的整体就叫做集合框架,在进行JAVA应用程序开发时,可以根据需要创建相应的对象,而不必再去设计数据结构和具体的算法实现,这样就大大提高了编程效率。

2、集合框架的结构(jdk1.8)

JAVA集合框架主要由两个接口派生而出,分别是Collection接口进入Map接口,这是集合框架的两个根接口,其中Collection接口的实现类直接保存对象,而Map接口的实现类是用键值对(key-value)的形式保存数据的,可以根据key值获取相应的value值。下面来看他们具体的结构吧。

2.1、Collection框架结构

在这里插入图片描述
上图展示了Collection体系里的集合,其中紫色的代表的是接口,淡蓝色的代表的是具体的实现类。根据上图可以知道,Collection接口下面有三个子接口,分别是List、Queue、Set。三个子接口下面就是他们具体的一些实现类了。实际中国常用的类有ArrayList、HashSet、TreeSet等等。至于这些类的源码分析后期会具体分析。

现在先来看一下List接口和Set接口的区别:

在这里插入图片描述
再来看一下三个接口下面常用的ArrayList、LinkedList、HashSet三个子类的一些简单的区别吧。

在这里插入图片描述
那么最后一个问题,上述集合实现类中有哪些是线程安全的呢?

  • 在上述Collection接口结构图中,线程安全的只有Vector和Stack,其余的都是线程不安全的。
  • 线程安全的List有Collections.synchronizedList
  • 在jdk的java.util.concurrent包下的所有集合类都是线程安全的。比如CopyOnWriteArrayList、CopyOnWriteArraySet、SynchronousQueue等。
2.2、Map框架结构

Map接口的实现类是用键值对(key-value)的形式保存数据的,可以根据key值获取相应的value值,值得注意的是Map接口的所有实现类中的key是不可重复的。下面来看看Map接口的具体结构吧。

在这里插入图片描述
如上图所示,Map接口下面有很多的实现类,下面简单的介绍一下主要的几个实现类的底层数据结构、是否线程安全等一些特点:

在这里插入图片描述
除了上面已知的HashTable是线程安全的,你还知道那些线程安全的Map类呢?

  • 应该很容易猜到了,jdk下面的java.util.concurrent包下的所有Map类都是线程安全的,比如经常说ConcurrentHashMap。juc包是jdk的线程并发包。有兴趣的同学可以去研究一下。
3、集合的遍历

集合的遍历有两种方式:分别是for循环和、foreach循环和Iterator接口遍历。下面分析一下它们三个遍历速度的快慢及其底层原理。

3.1、for循环原理

for循环遍历是基于元素的位置,按位置进行读取,通俗的来讲就是对元素的下标进行直接访问,因此对于顺序存储的数据结构(例如数组),对特定位置的元素查询的平均时间复杂度是O(1)。而对非顺序存储的数据结构(如链表),那么读取特定位置元素的平均时间复杂度是O(n)。

3.2、Iterator循环原理

Iterator接口是所有集合框架的父接口,它每次遍历集合的时候都需要保存当前遍历的位置,然后根据当前位置来向前或者向后移动指针,直至循环完当前所有的元素。因此对于任何集合来说,它的平均时间复杂度为O(n)。

3.3、foreach循环原理

通过Java字节码可以知道,foreach内部实现也是通过Iterator实现的,只时这个Iterator是由Java编译器生成的,因此时间复杂度和Iterator一样。但是因为foreach每次都要做类型转换检查,所以花费的时间比Iterator略长。

总结: for循环、foreach循环和Iterator循环的遍历速度需要根据具体集合的数据结构进行判定,

  • 对于顺序存储的集合如ArrayList,那么此时的遍历速度:for > Iterator > foreach
  • 对于非顺序存储的集合如LinkedList,那么此时的遍历速度:Iterator > foreach > for
3.4、demo演示

用for循环和foreach循环遍历List集合, 用Iterator遍历

public class ArrayListTest {
    public static void main(String[] args) {

        //定义List
        ArrayList<String> list = new ArrayList<>();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        //for循环遍历
        for (int index = 0; index < list.size(); index++) {
            System.out.println(list.get(index));
        }
        //foreach循环遍历
        list.forEach(s -> System.out.println(s));

        //定义HashMap
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("key1", "value1");
        hashMap.put("key2", "value2");
        //遍历hashMap
        Iterator it = hashMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            System.out.println("打印Key值" + entry.getKey());
            System.out.println("打印Vaule值" + entry.getValue());
        }
    }
}
4、面试相关
  • 说一下你对集合类的认识?
    JAVA的集合类是对数据结构的封装,集合类存储的数据类型是引用数据类型,集合框架的有两个根接口:Collection接口和Map接口,其中Collection接口有List接口、Set接口、Queue接口。Map接口的实现类有HashMap、TreeMap、HashTable等。
  • List和Set有什么区别?
    在这里插入图片描述
  • 你知道哪些线程安全的集合类?
    Collection下面有Vector和Stack,Map下面有HashTable,EnumTable。另外jdk下面的java.util.concurrent包下的所有集合类都是线程安全的。
  • List集合和数组有什么区别?
    1>集合大小不固定;但是数组长度是固定的,一旦创建无法改变;
    2>集合可以存放多种类型(不加泛型时添加的类型是Object);而数组的存放的类型只能是一种,
    3>ArrayList是基于数组创建的容器类

欢迎各位关注我的JAVAERS公众号,陪你一起学习,一起成长,一起分享JAVA路上的诗和远方。在公众号里面都是JAVA这个世界的朋友,公众号每天会有技术类文章,面经干货,也有进阶架构的电子书籍,如Spring实战、SpringBoot实战、高性能MySQL、深入理解JVM、RabbitMQ实战、Redis设计与实现等等一些高质量书籍,关注公众号即可领取哦。

在这里插入图片描述


如果大家对人工智能感兴趣,可以关注下面公众号,会持续更新c++、python、tensorflow、机器学习、深度学习、计算机视觉等系列文章
在这里插入图片描述

  • 33
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 20
    评论
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值