【Java基础】Java集合解析

0、前言

首先提出几个问题,Java为什么要提供集合框架?没有集合框架的话我们还能编程吗?集合框架需要提供哪些基本的功能?

我们知道,程序本质上是通过算法对数据的操作,这样看,当有了基本类型和引用类型的数据类型以后,我们便可以创建变量/对象并通过给变量/对象赋值实现逻辑和数据的流转。然而实际上,我们要面临的问题是,我们往往不是操作某个单一变量/对象,而是要批量操作数据,这样就要求编程语言能够一次性对一批相同类型的变量/对象做处理,需要能够承载这一批对象的容器,集合的概念应运而生。

通常,集合要具有(但不限于)以下功能:

  • 能够添加、删除元素
  • 能够计算本身大小
  • 能够增大、减小本身容量
  • 能够迭代遍历每个元素

1、Java集合框架

Java集合框架根据源头接口实现可以分为Collection和Map,Collection是一组有序或者无序的元素集合,Map是一组<key, value>键值对集合(EntrySet)。

Collection和Map的层次结构(hierarchy)如图所示
在这里插入图片描述

1.1、Java Collection

1.1.1、Collection的行为

Collection接口继承了Iterable接口,Iterable具有以下行为:

  • iterator():返回一个迭代器Iterator;

  • forEach():遍历元素,并执行传入的参数方法。

而迭代器Iterator作为一个接口,具有以下行为:
在这里插入图片描述

  • forEachRemaining:这是Java 8为Iterator新增的默认方法,该方法可使用Lambda表达式来遍历集合元素
  • hasNext:判断容器内是否还有可供访问的元素
  • next:返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型
  • remove:删除迭代器刚越过的元素

1.1.2、Collection的层次结构

Collection有三个子接口,分别是List,Set和Queue。

1.1.2.1、List

1、List的行为

在这里插入图片描述

2、List的特点

  • 元素有序
  • 可重复
  • 允许面向索引位置操作元素

3、List的子接口或实现

  • ArrayList
  • Vendor
  • LinkedList
ArrayList Vendor LinkedList Stack
线程安全
底层实现 动态数组 数组 双向链表
特点 查询快,增删慢 最慢 增删快,查询慢 继承自Vector,后进先出
1.1.2.2、Set

1、Set的行为

在这里插入图片描述

2、Set的特点

  • 无序的
  • 不允许重复元素(和hashcode与equals方法直接相关)
  • 最多有一个null元素

3、Set的子接口或实现

  • HashSet
  • TreeSet
  • LinkedHashSet
  • EnumSet
HashSet TreeSet LinkedHashSet
线程安全
底层实现 哈希表(HashMap) 红黑树(TreeMap) 哈希表和链表(LinkedHashMap)
特点 无序,最多一个null元素 有序,元素可为null 有序,元素可为null
1.1.2.3、Queue

1、Queue的行为

在这里插入图片描述

2、Queue的特点

  • 一个队列就是一个先入先出(FIFO)的数据结构
  • 继承了Collection接口
  • 子接口Deque(LinkedList实现)

3、Queue的子接口或实现

  • 非阻塞队列
    • PriorityQueue:维护了一个有序列表。加入到 Queue 中的元素根据它们的天然排序(通过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。
    • ConcurrentLinkedQueue:基于链接节点的、线程安全的队列。并发访问不需要同步。因为它在队列的尾部添加元素并从头部删除它们,所以只要不需要知道队列的大小,ConcurrentLinkedQueue 对公共集合的共享访问就可以工作得很好。收集关于队列大小的信息会很慢,需要遍历队列。
  • 阻塞队列-BlockingQueue 接口
    • ArrayBlockingQueue:一个由数组支持的有界队列。
    • LinkedBlockingQueue:一个由链接节点支持的可选有界队列。
    • PriorityBlockingQueue:一个由优先级堆支持的无界优先级队列。
    • DelayQueue:一个由优先级堆支持的、基于时间的调度队列。
    • SynchronousQueue:一个利用 BlockingQueue 接口的简单聚集(rendezvous)机制。

1.2、Java Map

Map是由一系列键值对组成的集合,提供了key到Value的映射。在Map中它保证了key与value之间的一一对应关系。也就是说一个key对应一个value,所以它不能存在相同的key值,value值可以相同。

1.2.1、Map的行为

在这里插入图片描述

1.2.2、Map的层次结构

Map有5个具体的实现(HashMap/Hashtable/TreeMap/IdentityHashMap/WeakHashMap)和一个接口(SortedMap)

1.2.2.1、HashMap
  • 非线程安全的
  • 底层实现:数组+链表,当链表长度大于8时转数组+红黑树
  • 长度始终是2的幂次方
  • 扩容:2n
  • 允许一个key=null,多个value=null

LinkedHashMap继承自HashMap,它保留元素顺序,因此性能稍逊于HashMap

1.2.2.2、TreeMap
  • 非线程安全
  • 底层实现:基于红黑树,每一个key-value节点作为红黑树的一个节点
  • 有序
    • 自然排序:TreeMap中所有的key必须实现Comparable接口,并且所有的key都应该是同一个类的对象,否则会报ClassCastException异常。
    • 定制排序:定义TreeMap时,创建一个comparator对象,该对象对所有的treeMap中所有的key值进行排序,采用定制排序的时候不需要TreeMap中所有的key必须实现Comparable接口。
  • 判断两个元素相等:两个key通过compareTo()方法返回0,则认为这两个key相等。如果使用自定义的类来作为TreeMap中的key值,且想让TreeMap能够良好的工作,则必须重写自定义类中的equals()方法,TreeMap中判断相等的标准是:两个key通过equals()方法返回为true,并且通过compareTo()方法比较应该返回为0。
1.2.2.3、Hashtable
  • 线程安全,内部的方法都经过synchronized修饰(但推荐使用CurrentHashMap)
  • 底层实现:
  • key=null时,抛出NullPointerException
  • 扩容:2n+1
1.2.2.4、IdentityHashMap

1.2.2.5、WeakHashMap

2、附

2.1、集合和数组的区别

2.1.1、长度限制之别

  • 数组长度是固定不变的
  • 集合的大小是可动态变化的

2.1.2、存储类型之别

  • 一个数组存储的元素可以是基本类型,也可以是引用类型,且只能存储同一种类型的元素
  • 一个集合存储的元素只能是引用类型,但集合可以存储不同类型的元素(但集合一般存储同一种类型,可以用泛型加以控制)

2.1.3、访问元素方式

  • 数组是根据索引来获取元素的
  • 集合通常会提供一个迭代器来方便访问元素

2.2、集合工具类-Collections

2.3、数组工具类-Arrays

2.4、集合常见面试问题

1、说一说List,Set,Map的区别?

2、ArrayList和LinkedList区别?

3、ArrayList和Vector的区别?

4、ArrayList的扩容?

5、HashMap的扩容?

6、Hashtable的扩容?

7、HashMap和Hashtable的区别?

8、HashMap和HashSet的区别?

9、HashMap的底层实现?

10、HashSet如何检查重复?

11、CurrentHashMap的底层实现?

12、CurrentHashMap和Hashtable的区别?

13、HashMap多线程操作时为什么容易造成死循环?

发布了11 篇原创文章 · 获赞 5 · 访问量 6883

猜你喜欢

转载自blog.csdn.net/C1248770189/article/details/105052970