Java的集合类
转自:Q.Mr的博客
http://www.cnblogs.com/zrtqsk/p/3472258.html
(本人第一次写博客,部分内容有参照李刚老师的疯狂java系列图书,如有遗漏错误,请多指教,谢谢。)
Java的集合类可分为Set、List、Map、Queue,其中Set、List、Queue都有共同的接口:Collection.
所以Collection和Map是Java集合框架的根接口。Java集合实际上并不是真的把对象放入其中,集合中保存的只是对象的引用。
这里首先讲Map,因为所有的Set底层都是由Map实现的,仔细观察API可以发现,Set集合继承体系中所有的接口、实现类的类名,对应的Map集合体系都有。
如:Set-->Map
EnumSet-->EnumMap
SortedSet-->SortedMap
TreeSet-->TreeMap
NavigableSet-->NavigableMap
HashSet-->HashMap
LinkedHashSet-->LinkedHashMap
所不同的是,Map集合体系中还包括IdetityHashMap、WeakHashMap、Hashtable、Properties实现类。
Map集合用于保存具有映射关系的数据,其本质就是一个Object类型的动态数组,数组元素是Map接口的内部类Entry。
内部类Entry封装了一个key-value对。
key和value存在单向的一对一关系,通过指定的key总能找到唯一的确定的value.
由于这个特征,就必须要求Key是不可重复的,符合Set的特征。事实上,Map中所有的key就组成了一个Set集合。
而Value是可以重复的。只能通过key查询value,可以把value看作key的附庸。
一、HashMap 和 Hashtable
Hashtable较为古老,是HashMap的线程安全形式。其中封装了许多古老的方法,与HashMap主要有两点区别:
1、HashMap线程不安全,Hashtable线程安全,所以HashMap性能更好。
而实现线程安全用集合工具类Collections的静态方法synchronizedMap()包装一下,更简单、实用。
2、Hashtable不允许使用null作为key和value,会引发NullPointerException异常,而HashMap允许。
HashMap的底层是数组实现的,其数组元素为一个Entry链表(栈)。
存储过程:根据元素的hashCode()返回值计算元素在数组中的存储索引。根据元素equals方法来计算元素在Entry链表中的存储位置。
若有2个元素hashCode()返回值相同而equals为false,那么发生哈希冲突。新增加的Entry总放在Entry链表栈顶。
HashMap底层数组默认大小为16,这种存储位置又叫做桶(bucket),默认负载极限为0.75,即当HashMap中填满3/4时,
HashMap的容量将自动增加一倍。这个过程中,元素会重新分配,放入新的桶中。这个过程叫做rehashing.

public V put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
return null;
}

static int indexFor(int h, int length) {
return h & (length-1);
}
可以看到:1、元素的hash值是根据key的hashCode计算的。
2、索引是根据元素的hash值简易计算的。
查询过程:与存储过程类似,先根据hashCode()返回值计算数组索引,若数组所在位置已经有元素,与栈中所有元素equals比较,若相同,则返回。

public V get(Object key) {
if (key == null)
return getForNullKey();
int hash = hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

所有参与计算hashCode()返回值的关键属性,都应用于作为equals()比较的标准。
不应该给equals()和hashCode()方法的依赖属性提供注入方法,或者可以直接将其设置为final.
创建过程:除了默认的构造方法,HashMap还提供了指定初始容量、负载因子的构造器。

public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
// Find a power of 2 >= initialCapacity
int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1;
this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}

可以看到:1、初始容量最大为1<<30。不可以更大。
2、初始容量必须为大于指定容量的最小的2的n次方值
二、TreeMap
TreeMap采用“红黑树”的排序二叉树来保存Map中的每个Entry。每个Entry为红黑树的一个节点。
所有的Entry总是根据key按指定的规则保持有序。
红黑树是一种自平衡二叉树,每个节点的值都大于或等于它的左子树中所有节点的值,都小于或等于它的右子树中所有节点的值。
三、WeakHashMap、IdentityHashMap
WeakHashMap每个key对象保存了实际对象的弱引用。
IdentityHashMap的实现机制与HashMap类似,只有当key1==key2时,才认为key1与key2相等。它不保证任何key-value对之间的顺序,
也不保证它们的顺序随时间的推移不变。
四、LinkedHashMap、Properties
LinkedHashMap是HashMap的子类,使用双向链表来维护entry的插入次序,迭代输出时,元素顺序与插入顺序一致。
Properties也是HashMap的子类,把Map对象和属性文件关联起来,把Map对象的key和value与属性文件的属性名和属性值关联起来。
五、EnumMap
1、EnumMap所有key必须是枚举类的枚举值。
2、在内部以数组实现,根据key自然排序。
3、不允许使用null作为key,允许使用null作为value
4、创建EnumMap时必须指定一个枚举类,将EnumMap与指定枚举类关联起来。
5、EnumMap是性能最好的Map
另:Map有一个values方法,返回一个集合对象,
其实,这个Values集合对象并未盛装任何java对象,主要用来遍历map中的所有value值。
Java的集合类的更多相关文章
- java基础 集合类
java集合类主要有以下集中: List结构的集合类: ArrayList类, LinkedList类, Vector类, Stack类 Map结构的集合类: HashMap类,Hashtable类 ...
- 首先java中集合类主要有两大分支
本文仅分析部分原理和集合类的特点,不分析源码,旨在对java的集合类有一个整体的认识,理解各个不同类的关联和区别,让大家在不同的环境下学会选择不同的类来处理. Java中的集合类包含的内容很多而且很重 ...
- Java:集合类的区别详解
Java中集合类的区别 Array是数组,不在集合框架范畴之内,一旦选定了,它的容量大小就不能改变了,所以通常在编程中不选用数组来存放. 集合 : 集合对象:用于管理其他若干对象的对象 数组:长度不可 ...
- java中集合类中Collection接口中的List接口的常用方法熟悉
1:集合类,在java语言中的java.util包提供了一些集合类,这些集合类又被称作容器. 2:区别集合类和数组.(1)数组的长度是固定的,集合的长度是可变的.(2)数组是用来存放基本数据类型的,集 ...
- Java Map 集合类简介
作者:Jack Shirazi 了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map. 本文相关下载: · Jack 的 HashMap 测试 · Oracle ...
- Java常用集合类详解
在Java中有一套设计优良的接口和类组成了Java集合框架,使程序员操作成批的数据或对象元素极为方便.所有的Java集合都在java.util包中. 在编写程序的过程中,使用到集合类,要根据不同的需求 ...
- JAVA Map集合类简介
了解最常用的集合类型之一 Map 的基础知识以及如何针对您应用程序特有的数据优化 Map. 本文相关下载: · Jack 的 HashMap 测试· Oracle JDeveloper 10g jav ...
- java的集合类【转】
在JDK API中专门设计了一组类,这组类的功能就是实现各种各样方式的数据存储,这样一组专门用来存储其它对象的类,一般被称为对象容器类,简称容器类,这组类和接口的设计结构也被统称为集合框架(Colle ...
- Java之集合类
出处:http://blog.csdn.net/zhangerqing 一.集合类简介 数组是很常用的一种的数据结构,我们用它可以满足很多的功能,但是,有时我们会遇到如下这样的问题: 1.我们需要该容 ...
随机推荐
- 20145206《Java程序设计》实验五Java网络编程及安全
20145206<Java程序设计>实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 我和201451 ...
- Asp.Net - 8.多线程
8.1 概念 进程(Process):是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源.进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方式),一个 ...
- EF – 8.多对多关联
5.6.10 <多对多关联(上)> 时长:9分57秒 难度:难 5.6.11<多对多关联(下)> 时长:8分50秒 难度:难 如果单独地把多对多关联的CRUD拿出来讲,确实比较 ...
- 重温WCF之一个服务实现多个契约(二)
public class ServiceImp : IService1,IService2,IService3 { public string SayHelloA() { return "你 ...
- ASP.NET Web Api 使用CacheCow和ETag缓存资源(转载)
转载地址:http://www.cnblogs.com/fzrain/p/3618887.html 前言 本文将使用一个开源框架CacheCow来实现针对Http请求资源缓存,本文主要介绍服务器端的缓 ...
- poj 1002:487-3279(水题,提高题 / hash)
487-3279 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 236746 Accepted: 41288 Descr ...
- 攻城狮在路上(壹) Hibernate(十一)--- 映射实体关联关系
本文以Customer和Address类的关系为例说明一对一关联映射:以Category和Item类的关系说明多对多关联关系.一.映射一对一关联: 分两种情况:按照外键映射和按照主键映射.这两种方式的 ...
- 杂物 python (一)
python 是一门语言,有各种不同的实现.CPython 即用c语言实现Python及其解释器.
- ZooKeeper 的羊群效应
一个需要避免的问题是当一个特定的znode 改变的时候ZooKeper 触发了所有watches 的事件. 举个例子,如果有1000个客户端watch 一个znode的exists调用,当这个节点被创 ...
- CodeIgniter类的使用
Email 类 在配置文件中设置 Email 参数 如果您不想使用使用上述方法设定参数,您可以把它们放入一个配置文件.创建一个新文件称为email.php ,添加$config数组在该文件中.然后将该 ...