一、ArrayList

长度可变数组,类似于c++ STL中的vector.

元素以线性方式连续存储,内部允许存放重复元素。

允许对元素进行随机的快速访问,但是向ArrayList中插入和删除元素的速度较慢。

ArrayList是非线程安全的,若要成为线程安全,可以使用:List list=Collections.synchronizedList(new ArrayList());

数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。

这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。

当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。

二、LinkedList

内部采用双向循环链表实现,类似于c++ STL中的list.

插入和删除元素的速度较快,随机访问的速度较慢.

LinkedList单独具有addFirst(),addLast(),getFirst(),getLast(),removeFirst()和removeLast()方法.

这些方法使得它可以作为堆栈、队列和双向队列来使用.

LinkedList也是非线程安全的.

三、HashMap

基于哈希表的Map接口实现,类似于c++ STL中的unordered_map.

元素是无序的.

采用拉链法来处理哈希冲突,注意:链表中存储的仍然是key值,而非value,对于同一个key,value的新值会替换旧值.

当哈希表中的条目数超过了加载因子与当前容量的乘积时,则要对该哈希表进行rehash操作(重建内部数据结构),将哈希的桶数量扩大两倍左右.

HashMap是基于HashCode的,HashMap也是非线程安全的,若要线程安全,可用:Map m=Collections.synchronizedMap(new HashMap());

自己实现,最好使用局部锁:把HashMap进行拆分,拆分成了多个独立的块,这样在高并发的情况下减少了锁冲突的可能,增加了并发性.

四、TreeMap

基于红黑树,类似于c++ STL中的map.

使用了SortedMap接口.

确保key键是有序的,无重复的.

也是非线程安全的.

五、HashSet

基于Hash表的Set接口实现,类似于c++ STL中的unordered_set,采用hash散列存储.

元素是无序的,无重复的.

也是非线程安全的.

六、TreeSet

基于红黑树实现,类似于c++ STL中的set.

TreeSet 底层实际使用的存储容器就是TreeMap.

元素是有序的,无重复的.

也是非线程安全的.

七、总结

Java中的容器大多在c++ STL中都有实现,实现方法和使用方法都大同小异.

在Java容器中,只有HashTable和Vector是线程安全(同步)的,同步实现的方法是:

将状态封闭起来,并对每个共有方法进行同步,是的每次只有一个线程能访问容器状态,并发性较差.

------------------------------------------------------------------------------------------

什么是Map.

  在数组中我们是通过数组下标来对其内容索引的,而在Map中我们通过对象来对对象进行索引,用来索引的对象叫做key,其对应的对象叫做value.这就是我们平时说的键值对.

  HashMap通过hashcode对其内容进行快速查找,而TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的).

  HashMap 非线程安全 TreeMap 非线程安全

线程安全

  在Java里,线程安全一般体现在两个方面:

  1. 多个thread对同一个java实例的访问(read和modify)不会相互干扰,它主要体现在关键字synchronized.

  如ArrayList和Vector,HashMap和Hashtable(后者每个方法前都有synchronized关键字)。

  如果你在interator一个List对象时,其它线程remove一个element,问题就出现了.

  2. 每个线程都有自己的字段,而不会在多个线程之间共享. 它主要体现在java.lang.ThreadLocal类,而没有Java关键字支持,如像static. transient那样.

1.AbstractMap抽象类和SortedMap接口

  AbstractMap抽象类:(HashMap继承AbstractMap)覆盖了equals()和hashCode()方法以确保两个相等映射返回相同的哈希码. 如果两个映射大小相等. 包含同样的键且每个键在这两个映射中对应的值都相同,则这两个映射相等. 映射的哈希码是映射元素哈希码的总和,其中每个元素是Map.Entry接口的一个实现. 因此,不论映射内部顺序如何,两个相等映射会报告相同的哈希码.

  SortedMap接口:(TreeMap继承自SortedMap)它用来保持键的有序顺序. SortedMap接口为映像的视图(子集),包括两个端点提供了访问方法. 除了排序是作用于映射的键以外,处理SortedMap和处理SortedSet一样. 添加到SortedMap实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现. TreeMap类是它的唯一一份实现.

2.两种常规Map实现

  HashMap:基于哈希表实现. 使用HashMap要求添加的键类明确定义了hashCode()和equals().

可以重写hashCode()和equals()。为了优化HashMap空间的使用,您可以调优初始容量和负载因子.

  • HashMap(): 构建一个空的哈希映像
  • HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射
  • HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像
  • HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像

  TreeMap:基于红黑树实现. TreeMap没有调优选项,因为该树总处于平衡状态.

  • TreeMap():构建一个空的映像树
  • TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素
  • TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序
  • TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序

3.两种常规Map性能

  •   HashMap:适用于在Map中插入. 删除和定位元素.
  •   Treemap:适用于按自然顺序或自定义顺序遍历键(key).

4.总结

  HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap.

------------------------------------------------------------------------------------------

 

一、Collection:存放独立元素

Collection中的接口都是可选操作,事实上现类 并不一定实现了其全部接口,这是为了防止“接口爆炸”。

最常见的Unsupported Operation都源自于背后由固定尺寸的数据结构支持的容器,比方使用ArrayList.asList将数组转换成List的时候,就会得到这种容器。

 (1)Collection之List

List较之Collection添加了非常多额外的接口,特别是LinkedList。

长处

缺点

保存元素的顺序

应用

ArrayList            

随机訪问速度快,内部使用数组实现。

迭代,插入和删除元素慢,

尤其是当List尺寸比較大的时候。

插入顺序

可变长数组

LinkedList

迭代(顺序訪问经过优化),插入、删除都非常快

内部使用双向链表实现

随机訪问速度慢

插入顺序

顺序訪问, 批量插入删除元素的场合

(2)Collection之Set

存入Set的每个元素都必须是唯一的,由于Set不保存重复元素。

可是存入Set的元素必须要定义equals()方法以确保对象的惟一性。

另外Set与Collection有着全然同样的接口。

Set并不保证维护元素的次序,所以须要注意。

Set不包括随机訪问的get方法。由于Set是自己维护内部顺序的,不须要随机訪问。

长处

保存元素的顺序

要求

HashSet

为快速查找设计

散列存储

必须定义hashCode()方法

LinkedHashSet

和HashSet一样的查询速度,

可是插入要比HashSet慢一些,

由于它通过维护链表形式维护元素。

使用链表维护元素顺序(插入顺序)

必须定义hashCode()方法

TreeSet

保存有序的Set,底层通过TreeMap来实现的

依照排序顺序维护元素

必须实现Comparable接口(包括compareTo方法)

注意,假设没有特别的限制,HashSet就应该是你的默认选择,由于它对速度进行了优化。

(3)Collection之Queue:

特点

保存元素的顺序

LinkedList

LinkedList除了普通List之外,

还加入了<队列、栈、双向队列>三种数据结构的方法。

尤其是模拟Queue的时候在两端插入删除元素非常快(经过了优化)。

插入的顺序

PriorityQueue

依照排序顺序取出元素,所以要求必须实现Comparable接口。

排序顺序

二、Map:存放键-值对

为了保证Map中的唯一性,不论什么“键”都须要有一个equals()方法,推断当前键是否与表中的键同样。

特点

保存元素的顺序

要求

HashMap

Map基于散列存储。插入和查询“键值对”的开销是固定的。

散列存储

存入的键须要具备hashCode()方法,当然,返回的标识不一定要唯一

LinkedHashMap

为了提快速度散列了全部元素,插入查询仅仅比HashMap慢一点点,由于它在维护散列数据结构的同一时候还要维护链表(插入顺序)。 可是迭代訪问的时候更快。由于内部使用链表维护次序。

插入顺序

同样须要键实现hashCode()方法

TreeMap

Map基于红黑树的实现。所以所得的结果是经过排序的。

红黑树

为了排序。必须实现Comparable接口。

其它为解决特殊问题设计的Map还有IdentityHashMap。WeakHashMap,ConcurrentHashMap等。

实验证明。除了IdentityHashMap之外的其它全部Map,随着Map的尺寸变大,插入会明显变慢。可是查找的代价小非常多。我推測这是由于每次插入都要通过equals方法来确保键值的唯一性导致的,只是Map最经常使用的操作是查询操作,所以情况还比較乐观。

总结:

(1)要想让你的容器类型安全,须要使用泛型(否则编译器同意你向容器中插入各种不同类型,仅仅要是Object就可以);

(2)创建容器的时候尽量将其向上转型为接口,像这样:

  List<Apple> apples = newArrayList<Apple>();

使用接口的目的在于当你决定改动你的实现的时候。仅仅须要在创建的地方改动它就能够了。

(3)Java有大量的用于容器的卓越的方法,他们被封装到java.util.Collections类中,全部都是static方法。

比方Collections类中有unmodifiableMap/List/Set()方法设置Collection和Map为不可改动。还有synchronizedCollection/List/Set/Map等方法同步整个容器。

另外排序,填充,逆置,最大最小值等非常多方法也能够找到。

 

--------------------------------------------------------- End.

转载请注明:http://www.cnblogs.com/crazyacking/

Java - 容器详解的更多相关文章

  1. Java容器详解

    线性表,链表,哈希表是常用的数据结构,在进行Java开发时,JDK已经为我们提供了一系列相应的类来实现基本的数据结构.这些类均在java.util包中.在Java中,容器的类型主要有:List.Set ...

  2. 【Java入门提高篇】Day34 Java容器类详解(十五)WeakHashMap详解

    源码详解系列均基于JDK8进行解析 说明 在Java容器详解系列文章的最后,介绍一个相对特殊的成员:WeakHashMap,从名字可以看出它是一个 Map.它的使用上跟HashMap并没有什么区别,所 ...

  3. 黑马----JAVA迭代器详解

    JAVA迭代器详解 1.Interable.Iterator和ListIterator 1)迭代器生成接口Interable,用于生成一个具体迭代器 public interface Iterable ...

  4. Java ClassLoad详解

    Java ClassLoad详解 类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一.它使得 Java 类可以被动态加载到 Java 虚拟机中并执行.类加载器从 JDK 1. ...

  5. Java NIO 详解(一)

    一.基本概念描述 1.1 I/O简介 I/O即输入输出,是计算机与外界世界的一个借口.IO操作的实际主题是操作系统.在java编程中,一般使用流的方式来处理IO,所有的IO都被视作是单个字节的移动,通 ...

  6. [Spring学习笔记 1 ] Spring 简介,初步知识--Ioc容器详解 基本原理。

    一.Spring Ioc容器详解(1) 20131105 1.一切都是Bean Bean可是一个字符串或者是数字,一般是一些业务组件. 粒度一般比较粗. 2.Bean的名称 xml配置文件中,id属性 ...

  7. Java List详解,面试中应该如何解答关于List的问题

    对于面试,我们在介绍Java的List的时候,一般需要介绍到,什么是List?List包括什么?各自在用法上有什么区别,在存储上有什么区别?List需要注意什么?把这些问题串起来,我们可以这样介绍: ...

  8. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  9. Java集合详解3:Iterator,fail-fast机制与比较器

    Java集合详解3:Iterator,fail-fast机制与比较器 今天我们来探索一下LIterator,fail-fast机制与比较器的源码. 具体代码在我的GitHub中可以找到 https:/ ...

随机推荐

  1. node(redis)

    给出node下redis操作的简单例子: var redis = require("redis"), client = redis.createClient(6379,'127.0 ...

  2. http学习笔记(三)

    几乎所有的http通信都是由TCP/IP承载的.http好比一辆汽车,而TCP是一条公路,所有的汽车都要在公路上跑,看看http是如何在tcp这条公路上往返的. 首先简单地看看tcp,TCP连接是通过 ...

  3. 解决URL中文乱码问题

    在做一个HTTPS连接时, 要客户端合成一段HTTPS地址 如果地址含中文的话程序会crash, 检查发现原来是中文没有转码的原因 在NSString库里面找到了下面两个方法 - (NSString ...

  4. PMO到底什么样?(2)

    接上一篇,继续聊一聊PMO到底什么样. 交付功能,8大典型责任 1监控.评定和报告 项目办理单位从交付的视点必定要有监控评定.每个项目在要害的期间上它的进展是不是跟按期的相同:是不是有要害的专家在要害 ...

  5. _学生选课数据库SQL语句练习题

    1. 查询Student表中的所有记录的Sname.Ssex和Class列. select Sname,Ssex,t.sclass from STUDENT t 2. 查询教师所有的单位即不重复的De ...

  6. SQL SERVER 2005/2008 中关于架构的理解(二)

    本文上接SQL SERVER 2005/2008 中关于架构的理解(一)      架构的作用与示例 用户与架构(schema)分开,让数据库内各对象不再绑在某个用户账号上,可以解决SQL SERVE ...

  7. django创建项目

    django创建项目 安装django pip install django==1.9 Note: C:\Python34\Scripts\pip.exe 创建项目 django-admin star ...

  8. IOS开发之控件篇UICollectionViewControllor第一章 - 普通介绍

    1.介绍 UICollectionView和UICollectionViewControllor是IOS6.0后引入的新控件 使用UICollectionView必须实现三个接口: UICollect ...

  9. 隐藏自定义tabbar(关于tabbar的hide属性对于自定义无效)

    背景: 最近在做一个项目中 需要在tabbar中的一个子控制器中隐藏tabbar. 我是tabbar我是自定义的XIB 视图addsubview到tabbar上. 首先po 一个在网上查到的解决方法: ...

  10. JTMz换路径导致MySQL服务不能启动的问题

    问题: JTMz解压到我的机器上,运行一次后,把服务停止了,然后移到了另外一个路径,JTMz中自带的MySQL服务启动不起来了. 解决: 在注册表中修改 HKEY_LOCAL_MACHINE\SYST ...