Java容器概览

前言

由于去广州面试,已经好几天没有更新了,准备从这篇文章开始来回顾一下我所学的Java容器知识,首先对他们有一个大概的了解而后逐步深刻源码来进行相关的分析。java

为何须要有容器

不止Java中有本身的容器,其它开发语言也大都有本身实现的相关容器或者说集合。面试

在Java中,变量能够有基本数据类型,对象,以及数组编程

int a = 5;
Person p = new Person();
int[] arr = new int[5];复制代码

但随着愈来愈复杂的业务的出现,这些简单的数据类型已经不能知足业务的需求了,这时咱们就须要更为复杂的数据结构来支撑咱们的业务实现并简化开发人员的开发难度。api

举个最简单的例子,上面的 arr 数组长度为5,可是当咱们如今须要往其中放置大于5个的元素呢?这时候就须要咱们从新建立一个数组并将原数组一个一个复制过去,对于开发人员来讲是至关浪费时间的事,甚至一个不注意还可能出现数组越界的糟糕状况产生致使程序崩溃。因此ArrayList的存在就是解决这种问题的,固然不局限于此。数组

咱们若是是更复杂的数据结构呢?别担忧,Java还帮咱们实现了诸如HashMap的key-value等等复杂的数据结构。安全

容器是什么

容器主要包括 Collection 和 Map 两种,Collection 存储着对象的集合,而 Map 存储着键值对(key-value)的映射表。
容器,就是能够容纳其余Java对象的对象。Java Collections Framework(JCF)为Java开发者提供了通用的容器,其始于JDK 1.2,优势是:
  • 下降编程难度
  • 提升程序性能
  • 提升API间的互操做性
  • 下降学习难度
  • 下降设计和实现相关API的难度
  • 增长程序的重用性
Java容器里只能放对象,对于基本类型(int, long, float, double等),须要将其包装成对象类型后(Integer, Long, Float, Double等)才能放到容器里。不少时候拆包装和解包装可以自动完成。这虽然会致使额外的性能和空间开销,但简化了设计和编程,使开发者可以直接使用一些复杂的数据结构而不须要本身实现。

Java容器可以容纳任何类型的对象,这一点表面上是经过泛型机制完成,Java泛型不是什么神奇的东西,只是编译器为咱们提供的一个“语法糖”,泛型自己并不须要Java虚拟机的支持,只须要在编译阶段作一下简单的字符串替换便可。实质上Java的单继承机制才是保证这一特性的根本,由于全部的对象都是Object的子类,容器里只要可以存放Object对象就好了。 事实上,全部容器的内部存放的都是Object对象,泛型机制只是简化了编程,由编译器自动帮咱们完成了强制类型转换而已。JDK 1.4以及以前版本不支持泛型,类型转换须要显式完成。数据结构

Map


  • HashMap:基于哈希表实现。
  • HashTable:和 HashMap 相似,但它是线程安全的,这意味着同一时刻多个线程能够同时写入 HashTable 而且不会致使数据不一致。它是遗留类,不该该去使用它。如今可使用 ConcurrentHashMap 来支持线程安全,而且 ConcurrentHashMap 的效率会更高,由于 ConcurrentHashMap 引入了分段锁。
  • LinkedHashMap:使用双向链表来维护元素的顺序,顺序为插入顺序或者最近最少使用(LRU)顺序。
  • TreeMap:基于红黑树实现,是有序的。

Collection


1. Set

  • TreeSet:基于红黑树实现,支持有序性操做,例如根据一个范围查找元素的操做。可是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。
  • HashSet:基于哈希表实现,支持快速查找,但不支持有序性操做。而且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 获得的结果是不肯定的。
  • LinkedHashSet:具备 HashSet 的查找效率,且内部使用双向链表维护元素的插入顺序。

2. List

  • ArrayList:基于动态数组实现,支持随机访问。
  • Vector:和 ArrayList 相似,但它是线程安全的。
  • LinkedList:基于双向链表实现,只能顺序访问,可是能够快速地在链表中间插入和删除元素。不只如此,LinkedList 还能够用做栈、队列和双向队列。

3. Queue

  • LinkedList:能够用它来实现双向队列。
  • PriorityQueue:基于堆结构实现,能够用它来实现优先队列。

各个Java容器适用的场景

List

可用于数据出现重复的场景,与普通类型的数组相似并发

  • ArrayList:底层实现为数组,读取元素时间复杂度为O(1),适用于读多的场景
  • LinkedList:底层实现为链表,头尾操做及插入指定位置简单,适用于数据改变较多的场景
  • Vector:线程安全的ArrayList

Set

数据不重复的集合,可用于去重性能

  • HashSet:适用于对排序无要求的场景,且其get元素时间复杂度为O(1)
  • TreeSet:适用于要排序的场景

Map

是key-value类型的键值对,可用于须要数据匹配的场景,如学生学号对应学生类实体学习

  • HashMap:key-value存取。
  • ConcurrentHashMap:HashMap在并发环境中会出现线程不安全问题,须要使用ConcurrentHashMap来保证线程安全。
  • TreeMap:适用于须要排序的key-value数据类型的场景。

小结

容器的简单介绍到这里就结束了,细心的话你可能会发现,这些容器与咱们学习的数据结构有些类似之处,其实他们的底层原理就是对相应的数据结构进行了组合与封装,抽象出一套api供开发者使用。以后我会选取几个经常使用的比较重要的容器进行更加深刻的分析,Java中的容器没有好用与很差用之分,只有理解容器的底层的实现原理,才能更好地使用他们,并将他们用在合适的场景,发挥出最大的用处。

相关文章
相关标签/搜索