Java集合框架总结
java集合框架主要分为实现了Collection接口的List和Set、映射接口Map。
|-- List 有序,元素都有索引,可重复。
|-- Set 无序,不可以存储重复的元素。
|-- Map中的每个元素包含一个Key和一个对应的Value。
下图是java集合框架的体系结构
Collection接口
Collection接口是最基本的集合接口,他不提供直接的实现。
Collection所表示的是一种规则,它所包含的元素都必须包含一条或多条原则.eg:有些允许重复,有些不允许重复;有些要求按照顺序插入而有些则是散列;有些支持排序有些不支持。
所有实现了Collection接口的类都必须提供两套标准的构造函数,一个是无参,用于创建一个空的Collection;一个是带有Collection参数的有参构造函数,用于创造一个新的Collection,这个心得Collection与传进来的Collection具有相同的元素。
Collection接口的一些公有方法
主要就是增、删、判断、获取、取交集、变数组等。
List
List接口为Collection的直接接口。List代表的是有序的Collection,它用某种特定的顺序来维护元素的插入顺序。用户可对每个元素的精确的插入位置进行精确的控制,同时根据元素的索引获取元素。实现了List接口的集合主要有:ArrayList、LinkedList、Vector、Stack.
|--Vector 线程同步,增删查询都很慢。
|-- ArrayList 线程不同步,动态数组,ArrayList代替了Vector,允许插入null值,初始大小为10,擅长随机访问。
|-- LinkedList 线程不同步,双向链表,增删元素非常快。
|--Stack 继承自Vector,实现一个后进先出的堆栈。Stack在Vector的基础上增加了5个方法,使得其变为栈。Push、Pop、peek(获取栈顶)、empty、search(检测一个元素是否在堆中).
set
Set是一种不包括重复元素的Collection,他维持他的内部排序,允许null但仅能有一个,传入Set的元素必须不同。实现Set接口的集合有:EnumSet、HashSet、TreeSet.
|--EnumSet 枚举专用的Set,所有元素都是枚举类型。
|-- HashSet 底层是哈希表,线程不同步,无序,高效。HashSet堪称查询最快的集合,因为其内部是以HashCode实现的。它内部的顺序有哈希码来决定,所以不保证Set的迭代顺序。
|-- LinkedHashSet 有序 ,HashSet的子类。
|-- TreeSet 底层是二叉树, 线程不同步。 基于TreeMap,生成一个总是处于排序状态的Set,内部以TreeMap来实现,利用元素的自然顺序对元素进行排序,或者根据创建时提供的Comparator进行排序
Map
是由一系列键值对组成的集合,提供Key到Value的映射,不能存在相同的Key,实现Map的有:HashMap、TreeMap、HashTable、Properties、EnumMap . Map要保证键的唯一性。
|-- HashTable 底层哈希表,线程同步,不能存在Null键,Null值。线程同步,以哈希表的数据结构实现,解决冲突时与HashMap一样也是采用散列表的形式,不过性能比HashMap要低。
|--HashMap 底层哈希表,线程不同步,不能存在Null键,Null值。 以哈希表数据结构实现,查找对象时通过hash值计算其位置,它是为快速查询而设计的,内部定义了一个Hash表数组(Entry[] table),元素会通过hash转化函数转为在数组中的索引,如果有冲突的,则用散列链表的形式串起来。
|--LinkedHashMap Map接口的哈希表和链接列表实现,具有预知的迭代顺序。
|-- TreeMap 底层二叉树,可以对Map集合中的键进行制定顺序的排序。键以某种排序规则排序,内部以Red-balck(红-黑树)数据结构实现。实现了SortedMap接口。
(Queue
队列,主要分为两大类,一类是阻塞式队列,队列满了以后在插入会出现异常,ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue。另一种队列则是双端队列,支持在头、尾两端插入和移除元素,主要包括:ArrayDeque、LinkedBlockingDeque、LinkedList。)
下面按顺序对每一个容器进行详细讲解:
List --> Vector :
可以使用整数索引访问,可以看成数组的访问方式,但是与数组不同的是Vector大小会自动增长。
由 Vector 的 iterator 和 listIterator 所返回的迭代器是快速失败的:如果在迭代器创建后的任意时间从结构上修改了向量(通过迭代器自身的remove 或 add 方法之外的任何其他方式),则迭代器将抛出 ConcurrentModificationException。
Vector 的 elements 方法返回的 Enumeration 不是 快速失败的。
点击查看ConcurrentModificationException和Fail-Fast机制
List --> ArrayList :
实现了List接口,底层采用数组保存所有元素;动态数组,ArrayList是List接口的可变数组的实现;允许null值;不是同步的;实现了Cloneable()接口,级覆盖了clone()方法,能够被克隆。
1.set(int index, E element):该方法首先调用rangeCheck(index) 来校验 index 变量是否超出数组范围,超出则抛出异常。而后,取出原 index 位置的值,并且将新的 element 放入 Index 位置,返回 oldValue。
2.add(E e):该方法是将指定的元素添加到列表的尾部。当容量不足时,会调用 grow 方法增长容量。
3.add(int index, E element):在 index 位置插入 element。
4.addAll(Collection<? extends E> c) 和addAll(int index, Collection<? extends E> c) :将特定 Collection中的元素添加到 Arraylist 末尾。
数组扩容有两个方法,1:通过一个 public 的方法ensureCapacity(int minCapacity) 来增加 ArrayList 的容量。2:而在存储元素等操作过程中,如果遇到容量不足,会调用priavte方法private void ensureCapacityInternal(int minCapacity) 实现。
数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的 1.5 倍.
List --> LinkedList:
LinkedList 与 ArrayList一样,都实现了List接口,但内部的数据结构有本质的不同,LinkedList 是基于链表实现的,所以在类中包含了first和last两个指针,所以插入删除效率高,但随机访问效率低。
Set --> HashSet :
HashSet是基于HashMap实现的,底层是采用HahsMap来保存数据的,HashSet中会有一个HashMap成员,在构造函数中对其初始化。因为HashSet是基于HashMap实现的,所以关于HashSet的操作基本都是调用HashMap的方法来实现的。但是我们需要覆盖HashCode()和Equals()方法(用来保证放入的对象的唯一性)。
Set --> HashSet -->LinkedHashSet:
LinkedHashSet 继承HashSet、又基于LinkedHashMap来实现。
LinkedHashSet 是一个Set的实现,存的不是键值对,而是值。LinkedHashSet是不同步的。
LinkedHashSet 是Set的一个具体实现,其维护着一个运行于所有条目的双重链接列表,此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或访问顺序。
Set --> TreeSet :
不同步,当至少有一个线程修改了改set,则必须对外保持同步,一般是通过对自然封装该set的对象执行同步操作来完成,如果不存在这样的对象,则应该使用Collections.synchronizedSortedSet 方法来“包装”该 set。此操作最好在创建时进行,以防止对 set 的意外非同步访问:
SortedSet s=Collections.synchronizedSortedSet(new TreeSet(...)); 此类的iterator方法返回的迭代器是 快速失败 的。
Map --> HashTable:
任何非null的对象都可以做键或值,为了成功的在哈希表中存储和获取对象,用作键的对象必须实现hashCode()和equals()方法。
Map --> HashMap:
基于哈希表的Map实现,HashMap实际上是一个链表散列的数据结构,即数组和链表的结合体。底层是一个数组结构,而每个存储空间又是一个链表,当创建HashMap的时候会初始化一个数组。
允许存放Null Key和Null Value,当我们保存时,如果Key已经存在,则心得Value会覆盖旧的Value ,当我们执行put(此映射中关联指定值与指定键)操作时,先根据key的hashCode()计算出hash值,根据hash值得到这个元素在数组中的下标,如果数组中这个位置已经有元素了,则以链表的形式存放,新加入的放在链头,否则直接放到该位置。
确定存储Key-Value时,不考虑Value值,仅仅根据Key决定位置。
总结:HashMap在底层将Key-Value当成一个整体进行处理,这个整体是一个Entry对象,HashMap底层采用一个Entry[]数组来保存所有的Key-Value对。
当HashMap中的元素越来越多时,Hash冲突的机率越来越高。为了提高查询效率,就要对HashMap扩容,但是HashMap扩容是很消耗性能的:原数组中的数据必须重新计算其在新数组中的位置,并放进去。数组自动扩容(扩展两倍)时发生在:元素个数 > 数组长度(默认是16) * 负载因子(默认是0.75),当然,默认值可在初始化时像构造中传递参数。
负载因子是衡量一个散列表空间的散列程度的,负载因子越大表示填充的越满。(对使用链表法的散列表来说:负载因子越大,空间利用越充分,但查询效率就会降低)。
HashMap的遍历方式:
第一种:
Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue(); }
}
第二种:
Map map = new HashMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}
第一种效率比第二种高。
Map --> HashMap --> LinkedHashMap:
此实现不是同步的。如果多个线程同时访问链接的哈希映射,而其中至少一个线程从结构上修改了该映射,则它必须 保持外部同步。这一般通过对自然封装该映射的对象进行同步操作来完成。如果不存在这样的对象,则应该使用Collections.synchronizedMap 方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射的意外的非同步访问:
Map m=Colections.synchronizedMap(new LinkedHashMap(...));
Map --> TreeMap:
基于红-黑树(Ren-Black tree)实现。该映射根据其键的自然映射展开,或者根据创建映射时提供的Comparator进行排序,具体取决于使用的构造方法。
不同步,当至少有一个线程修改了改set,则必须对外保持同步,一般是通过对自然封装该set的对象执行同步操作来完成,如果不存在这样的对象,则应该使用Collections.synchronizedSortedSet 方法来“包装”该 set。此操作最好在创建时进行,以防止对 set 的意外非同步访问:
SortedMap m=Collections.synchronizedSortedMap(new TreeMap(...)); 此类的iterator方法返回的迭代器是 快速失败 的。
Java集合框架总结的更多相关文章
- Java集合框架List,Map,Set等全面介绍
Java集合框架的基本接口/类层次结构: java.util.Collection [I]+--java.util.List [I] +--java.util.ArrayList [C] +- ...
- Java集合框架练习-计算表达式的值
最近在看<算法>这本书,正好看到一个计算表达式的问题,于是就打算写一下,也正好熟悉一下Java集合框架的使用,大致测试了一下,没啥问题. import java.util.*; /* * ...
- 【集合框架】Java集合框架综述
一.前言 现笔者打算做关于Java集合框架的教程,具体是打算分析Java源码,因为平时在写程序的过程中用Java集合特别频繁,但是对于里面一些具体的原理还没有进行很好的梳理,所以拟从源码的角度去熟悉梳 ...
- Java 集合框架
Java集合框架大致可以分为五个部分:List列表,Set集合.Map映射.迭代器.工具类 List 接口通常表示一个列表(数组.队列.链表 栈),其中的元素 可以重复 的是:ArrayList 和L ...
- Java集合框架之map
Java集合框架之map. Map的主要实现类有HashMap,LinkedHashMap,TreeMap,等等.具体可参阅API文档. 其中HashMap是无序排序. LinkedHashMap是自 ...
- 22章、Java集合框架习题
1.描述Java集合框架.列出接口.便利抽象类和具体类. Java集合框架支持2种容器:(1) 集合(Collection),存储元素集合 (2)图(Map),存储键值对.
- Java集合框架实现自定义排序
Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...
- (转)Java集合框架:HashMap
来源:朱小厮 链接:http://blog.csdn.net/u013256816/article/details/50912762 Java集合框架概述 Java集合框架无论是在工作.学习.面试中都 ...
- Java集合框架
集合框架体系如图所示 Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框架位于java.util包中, 所以当使用集合框架的时候需要进行导包. Map接口的常用方法 Map接口提 ...
- Java集合框架(常用类) JCF
Java集合框架(常用类) JCF 为了实现某一目的或功能而预先设计好一系列封装好的具有继承关系或实现关系类的接口: 集合的由来: 特点:元素类型可以不同,集合长度可变,空间不固定: 管理集合类和接口 ...
随机推荐
- day3 自定义指令详解
在angular中,Directive,自定义指令的学习,可以更好的理解angular指令的原理,当angular的指令不能满足你的需求的时候,嘿嘿,你就可以来看看这篇文章,自定义自己的指令,可以满足 ...
- 合并css 合并图片 合并js
1:合并css 如:index.html 中的代码 <!DOCTYPE html><html lang="en"><head> <me ...
- springboot--mybatis--pagehelper分页整合不起作用
今天配置pagehelper,在pom文件中都使用的最新版本jar包,步骤都没问题,之后才发现是包的问题. 有问题:分页配置不起作用 <dependency> <groupId> ...
- vue-cli的使用
1.安装node https://nodejs.org/en/download/ 2.webpack安装[我选全局安装] 全局安装 npm install --global webpack 本地安装 ...
- [LeetCode] Minimum Factorization 最小因数分解
Given a positive integer a, find the smallest positive integer b whose multiplication of each digit ...
- PHP观察者模式与Yii2.0事件
1.先看PHP观察者模式的实现: 想要使用事件.必须实现事件的基类.统一的addObserver和trigger方法 定义统一接口.所有的观察者都要实现此接口 //事件的基类 abstract cla ...
- 机器学习技法:03 Kernel Support Vector Machine
Roadmap Kernel Trick Polynomial Kernel Gaussian Kernel Comparison of Kernels Summary
- 个人建站&mac下安装hexo
title: 个人建站&mac下安装hexo date: 2018-04-18 16:34:02 tags: [mac,blog,个人建站,markdown] --- 这两天使用了markdo ...
- Mac下安装oh-my-zsh
Mac下自带的终端并不好用,当你打开终端的时候是一个白花花的窗口,其实Mac自带几种shell,默认使用的是bash,可以通过 cat /etc/shells 查看几种shell bin/bash / ...
- [NOI 2007]货币兑换Cash
Description 题库链接 (按我的语文水平完全无 fa♂ 概括题意,找了 hahalidaxin 的题意简述... 有 \(AB\) 两种货币,每天可以可以付 \(IP_i\) 元,买到 \( ...