集合概述

集合:集合是Java中提供的一种容器,可以用来存储多个数据。

集合和数组的区别:

(1)数组长度的是固定的,集合的长度是可变的。

(2)数组中存储的都是同一类型的元素。集合存储的都是对象,对象的类型可以不一致。

Java集合类主要由两个根接口Collection和Map派生出来的。Collection有三个子接口: List、Set、Queue(Java5新增的队列)。Java集合大致也可分成List、Set、Queue、Map四种接口体系,注意:Map不是Collection的子接口。

Map接口:双列数据,保存具有映射关系“key-value对”

Collection接口

Collection接口:单列数据,定义了存取一组对象的方法的集合。

Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和 Queue集合。

Collection接口的常用方法

Collection子接口之一:List接口

List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。List集合默认按照元素的添加顺序设置元素的索引,可以通过索引(类似数组的下标)来访问指定位置的集合元素。

List接口的实现类主要有:ArrayListLinkedListVector

List接口的常用方法

返回值类型 方法名及描述
boolean add(E e) 将指定的元素追加到此列表的末尾(可选操作)。
void add(int index, E element) 将指定的元素插入此列表中的指定位置(可选操作)。
boolean addAll(Collection c) 按指定集合的迭代器(可选操作)返回的顺序将指定集合中的所有元素附加到此列表的末尾。
boolean addAll(int index, Collection c) 将指定集合中的所有元素插入到此列表中的指定位置(可选操作)。
void clear() 从此列表中删除所有元素(可选操作)。
boolean contains(Object o) 如果此列表包含指定的元素,则返回true。
E get(int index) 返回此列表中指定位置的元素。
int hashCode() 返回此列表的哈希码值。
int indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。
boolean isEmpty() 如果此列表不包含元素,则返回 true 。
Iterator iterator() 以正确的顺序返回该列表中的元素的迭代器。
int lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。
E remove(int index) 删除该列表中指定位置的元素(可选操作)。
E set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素。
int size() 返回此列表中的元素数。

(1)List接口的实现类之一:ArrayList

ArrayList是List接口的主要实现类,ArrayList是一个动态数组,允许任何符合规则的元素插入包括null。 它能快速随机访问存储的元素,支持随机访问, 查询速度快, 增删元素慢。

ArrayList的JDK1.8之前与之后的实现区别:

JDK1.7:直接创建一个初始容量为10的数组

JDK1.8:一开始先创建一个长度为0的数组,当添加第一个元素时再创建一个初始容量为10的数组

(2)List接口的实现类之二:LinkedList

LinkedList是List接口的另一个实现,除了可以根据索引访问集合元素外,LinkedList还实现了Deque接口。

LinkedList内部以链表的形式保存集合中的元素,所以随机访问集合中的元素性能较差,但在频繁的插入或删除元素时有较好的性能。

(3)List接口的实现类之三:Vector

Vector大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

 面试题:

ArrayList和LinkedList的区别

都是线程不安全,相对线程安全的Vector,执行效率高。此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList觉得优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。

ArrayList和Vector的区别

Vector和ArrayList几乎是完全相同的,唯一的区别在于Vector是同步类(synchronized),属于强同步类。因此开销就比ArrayList要大,访问要慢。大多数清空下使用 ArrayList而不是Vector,因为同步完全可以由自己来控制。Vector每次扩容请求其大小的2倍空间,而ArrayList是1.5倍。Vector还有一个子类Stack。

Collection子接口之二:Set接口

Set接口也是Collection的子接口,set接口没有提供额外的方法。

Set集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set集合中,则会添加操作失败。

Set集合判断两个对象是否相同是根据 equals() 方法,而不是使用 == 运算符。

(1)Set接口的实现类之一:HashSet

HashSet是Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。

HashSet按Hash算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。

HashSet 具有以下特点:

  • 不能保证元素的排列顺序

  • HashSet不是线程安全的

  • 集合元素可以是null

HashSet集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。

HashSet添加元素的原理如下:

当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据 hashCode值,通过某种散列函数决定该对象在HashSet底层数组中的存储位置。

如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果为true,则添加失败。如果为false,那么会保存该元素,但是该数组的位置已经有元素了, 那么会通过链表的方式继续链接存储。

如果两个元素的equals() 方法返回true,但它们的 hashCode() 返回值不相等,hashSet将会把它们存储在不同的位置,但依然可以添加成功。

重写hashCode() 方法的基本原则

在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值

当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()方法的返回值应该相等。

对象中用作equals()方法比较的实例变量,都应该用来计算hashCode值。

(2)Set接口的实现类之二:LinkedHashSet

LinkedHashSet是HashSet的子类。

LinkedHashSet也是根据元素的hashCode值来决定元素的存储位置。但它同时使用双向链表维护元素的次序,元素的顺序与添加顺序一致。

由于LinkedHashSet需要维护元素的插入顺序,因此性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。

LinkedHashSet不允许集合元素重复。

(3)Set接口的实现类之三:TreeSet

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

TreeSet底层使用红黑树结构存储数据元素。

TreeSet两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。

自然排序:

TreeSet会调用集合元素的compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。

如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable接口。

实现Comparable的类必须实现compareTo(Object obj) 方法,两个对象即通过compareTo(Object obj) 方法的返回值来比 较大小。

Comparable的一些典型实现类:

  • BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较

  • Character:按字符的 unicode值来进行比较

  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例

  • String:按字符串中字符的 unicode 值进行比较

  • Date、Time:后边的时间、日期比前面的时间、日期大

因为只有相同类的两个实例才会比较大小,所以向TreeSet中添加的应该是同一个类的对象。

对于TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj) 方法比较返回值。

当需要把一个对象放入TreeSet 中,重写该对象对应的equals() 方法时,应保证该方法与compareTo(Object obj) 方法有一致的结果。

对于TreeSet集合而言,它判断两个对象是否相等的标准是:两个对象通过compareTo(Object obj)方法比较是否返回0,如果返回0则相等。

定制排序

TreeSet的自然排序要求元素所属的类实现Comparable接口,如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素,希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。

利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2。

要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。

使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。

Map接口

Map与Collection并列存在。用于保存具有映射关系的数据:key-value

Map中的key和value都可以是任何引用类型的数据

Map中的key用Set来存放,不允许重复,即同一个Map对象所对应的类,须重写hashCode()和equals()方法

Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和Properties

(1)Map接口的实现类之一:HashMap

HashMap是Map接口使用频率最高的实现类。允许使用null键和null值,与HashSet一样,不保证映射的顺序。

所有的key构成的集合是Set:无序的、不可重复的。所以,key所在的类要重写:equals()和hashCode()

所有的value构成的集合是Collection:无序的、可以重复的。所以,value所在的类要重写:equals()

HashMap判断两个key相等的标准是:两个key通过equals() 方法返回true, hashCode值也相等。

HashMap判断两个value相等的标准是:两个value通过equals()方法返回true。

HashMap可以使用null值为key或value

HashMap源码中的重要常量

DEFAULT_INITIAL_CAPACITY: HashMap的默认容量,16

MAXIMUM_CAPACITY: HashMap的最大支持容量,2^30

TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,转化为红黑树。

UNTREEIFY_THRESHOLD:Bucket中红黑树存储的Node小于该默认值,转化为链表

table:存储元素的数组,总是2的n次幂

entrySet:存储具体元素的集

size:HashMap中存储的键值对的数量

modCount:HashMap扩容和结构改变的次数。

HashMap的存储结构

JDK8之前版本:

JDK8之前HashMap的存储结构是数组+链表结构(即为链地址法) ,当实例化一个HashMap时,系统会创建一个长度为Capacity的Entry数组,这个长度在哈希表中被称为容量 (Capacity),在这个数组中可以存放元素的位置我们称之“桶”(bucket),每个bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素。

每个bucket中存储一个元素,即一个Entry对象,但每一个Entry对象可以带一个引用变量,用于指向下一个元素,因此,在一个桶中,就有可能生成一个Entry链。 而且新添加的元素作为链表的head。

JDK8之后版本:

JDK8之后HashMap的存储结构是数组+链表+红黑树实现。当实例化一个HashMap时,会初始化initialCapacity和loadFactor,在put第一对映射关系时,系统会创建一个长度为initialCapacity的Node数组,这个长度在哈希表中被称为容量(Capacity),在这个数组中可以存放元素的位置我们称之为 “桶”(bucket),每个bucket都有自己的索引,系统可以根据索引快速的查找bucket中的元素。

每个bucket中存储一个元素,即一个Node对象,但每一个Node对象可以带一个引用变量next,用于指向下一个元素,因此,在一个桶中,就有可能生成一个Node链。也可能是一个一个TreeNode对象,每一个TreeNode对象可以有两个叶子结点left和right,因此,在一个桶中,就有可能生成一个TreeNode树。而新添加的元素作为链表的last,或树的叶子结点。

(2)Map接口的实现类之二:LinkedHashMap

LinkedHashMap 是 HashMap的子类,在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序。 该链表负责维护Map的迭代顺序,与插入顺序一致,因此性能比HashMap低,但在迭代访问Map里的全部元素时有较好的性能。

(3)Map接口的实现类之三:TreeMap

TreeMap存储Key-Value对时,需要根据key-value对进行排序。TreeMap可以保证所有的Key-Value对处于有序状态。底层采用红黑树的数据结构。

TreeMap也有两种排序方式,自然排序和定制排序。

(4)Map接口的实现类之四:Hashtable

HashMap线程不安全,Hashtable是线程安全的。

HashMap可以使用null值为key或value,Hashtable不允许使用null作为key和value。

Hashtable实现原理和HashMap相同,底层都使用哈希表结构,查询速度快。

Hashtable和HashMap一样也不能保证其中Key-Value对的顺序。

(5)Map接口的实现类之五:Properties

Properties类是Hashtable 的子类,该对象用于处理属性文件。

由于属性文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型 。

Collections工具类

Collections是一个操作 Set、List 和 Map 等集合的工具类。

Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作, 还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。

Iterator迭代器接口

Iterator接口用来遍历集合元素

Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了 Iterator接口的对象。

集合对象每次调用iterator()方法都得到一个全新的迭代器对象。

Java集合知识总结的更多相关文章

  1. 《面试补习》- Java集合知识梳理

    一.ArrayList ArrayList 底层数据结构为 动态数组 ,所以我们可以将之称为数组队列. ArrayList 的依赖关系: public class ArrayList<E> ...

  2. java 集合知识整理

    java集合类图 HashMap和Hashtable的区别   HashMap HashTable  继承方式 extends AbstractMap implements Map extends D ...

  3. Java 集合系列(四)—— ListIterator 源码分析

    以脑图的形式来展示Java集合知识,让零碎知识点形成体系 Iterator 对比   Iterator(迭代器)是一种设计模式,是一个对象,用于遍历集合中的所有元素.  Iterator 包含四个方法 ...

  4. Java 集合系列(三)—— LinkedList

    以脑图的形式来展示Java集合知识,让零碎知识点形成体系 LinkedList    LinkedList是一种可以在任何位置进行高效地插入和删除操作的有序序列.   它的最基本存储结构是一个节点:每 ...

  5. Java集合框架的知识总结(1)

    说明:先从整体介绍了Java集合框架包含的接口和类,然后总结了集合框架中的一些基本知识和关键点,并结合实例进行简单分析. 1.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象 ...

  6. Java集合框架的知识总结

    说明:面试准备,写的挺不错的. 转载地址: http://www.cnblogs.com/zhxxcq/archive/2012/03/11/2389611.html 1.综述 所有集合类都位于jav ...

  7. Java开发知识之Java中的集合Set接口以及子类应用

    ---恢复内容开始--- Java开发知识之Java中的集合Set接口以及子类应用 一丶Set接口以及作用 在上一讲.我们熟悉了接口的实现图.以及自己各有的子类. List接口主要存储的数据是可以重复 ...

  8. Java开发知识之Java中的集合上List接口以及子类讲解.

    Java开发知识之Java中的集合类 一丶什么是集合类 如果你学习说数据结构,那么学习集合就很简单. 因为集合就是存储数据的结构. 例如 有链表结构 (list ) 还有 map结构.等等. 集合类就 ...

  9. 集合框架基础知识-----java基础知识

    Java集合框架 :接口:Collection.List .Set. Map:实现类:ArrayList.LinkedList.Vector.HashSet.TreeSet.HashMap.HashT ...

随机推荐

  1. 基于docker部署skywalking实现全链路监控

    一.概述 简介 skywalking是一个开放源码的,用于收集.分析,聚合,可视化来自于不同服务和本地基础服务的数据的可观察的平台,skywalking提供了一个简单的方法来让你对你的分布式系统甚至是 ...

  2. msfconsole 常用命令记录

    Metasploit是一款开源的渗透测试框架,它现在还在逐步发展中,下面介绍的一些功能和命令,可能会在未来失效. Metasploit框架提供了多种不同方式的使用接口: msfgui msfconso ...

  3. 微信小程序封装请求接口

    var rootDocment = 'https://123.com';//你的域名 function postData(url, data, cb) { wx.request({ url: root ...

  4. Linux速通03 目录文件的浏览、管理和维护

    Linux文件系统的层次结构 # 树状结构:在Linux或Unix操作系统中,所有的文件和目录都被组织成一个以根节点开始的倒置的树状结构. # 目录的定义:目录相当于Windows中的文件夹,目录中存 ...

  5. Java I/O流 03

    I/O流·字符流 字符流FileReader * A:字符流是什么 * 字符流是可以直接读写字符的 IO流 * 字符流读取字符,就要先读取到字节数据,然后转换为字符:如果要写出字符,需要把字符转换为字 ...

  6. docker搭建redis集群和Sentinel,实现故障转移

    0.引言 公司开发需要用到redis,虽然有运维自动搭建,还是记录下如何搭建redis集群和Sentinel. 采用的是vagrant虚拟机+docker的方式进行搭建. 搭建思路: 首先是借鉴下其他 ...

  7. windows下MySQL如何完全卸载并安装行的版本

    卸载本地mysql之前,请务必要先将需要的数据库备份 停止mysql 服务 windows键-->搜索服务 找到mysql 服务,并停止他 卸载mysql server 在控制面板--程序 找到 ...

  8. springAop:Aop(Xml)配置,Aop注解配置,spring_Aop综合案例,Aop底层原理分析

    知识点梳理 课堂讲义 0)回顾Spring体系结构 Spring的两个核心:IoC和AOP 1)AOP简介 1.1)OOP开发思路 OOP规定程序开发以类为模型,一切围绕对象进行,OOP中完成某个任务 ...

  9. IDEA如何像ecplise一样添加jar包?

    以前使用ecplise开发代码,现在换成IDEA,有很多操作都不习惯,比如添加jar包.网上可以找到IDEA好几种添加jar包的方法,这里主要介绍在用IDEA开发时如何像ecplise一样添加jar包 ...

  10. mysql连接不上本地服务器或者localhost:3306报错

    今天初学MySQL数据库就遇到问题: 主要是本地服务器登录问题 workbench里双击那个connection出现的 解决方法: 1:看一看防火墙,这是最常见的,这种主要是防火墙限制了访问,可能是安 ...