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; } HashMap的put方法源代码 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; } HashMap的get方法
所有参与计算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(); } HashMap构造方法源代码
可以看到: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编程语言中,`Map`集合是一种存储键值对...总结来说,`Map`集合提供了键值对的存储,`Set`特性可用于排序和去重,而`IO流`则负责数据的输入输出。理解这些核心概念并熟练运用,对于进行高效的Java编程至关重要。
Map集合映射比较特殊,因为它的键和值都可以是任何对象。键通常映射到数据库的某个字段,而值则映射到另一个对象。以下是一个例子: ```xml <!-- User.hbm.xml --> <map name="properties" table="USER_PROPERTIES...
总结起来,Java中Map集合的遍历方法各有优缺点,选择哪种方式取决于具体需求,如是否需要键和值,是否关心遍历顺序,以及是否利用Java 8的Stream API进行更复杂的操作。在实际开发中,理解和熟练掌握这些遍历方式将...
### Map集合在Java中的应用与理解 #### 一、Map集合概述 Map接口是Java集合框架中的一个重要组成部分,它提供了一种将唯一键映射到特定值的方式。Map中的每个元素都包含一个键对象(key)和对应的值对象(value)...
### Map集合的四种遍历方式 #### 概述 在Java编程中,`Map`是一种常用的集合类型,用于存储键值对数据。由于其高效的数据查找特性,在实际开发中被广泛应用。本文将详细介绍如何通过四种不同的方法来遍历`Map`集合...
总结来说,遍历Map集合是在Java编程中十分基础且重要的操作,可以有多种方式实现。Map集合不仅限于存储基本类型的键值对,还可以存储复杂类型的对象,这为我们提供了极大的灵活性。对于Web开发者,了解如何在JSP页面...
这是对集合的总结,可以帮助我们对集合更深入更清晰的认识。
总结来说,Java中的Map集合提供了灵活且高效的方式来存储和操作键值对数据。选择哪种Map实现取决于具体需求,如是否需要排序、线程安全、插入和查找的效率等。理解Map的工作原理以及各种实现类的特点,对于编写高...
本文将详细介绍Java中Map集合的三种遍历方法及其应用场景、优缺点等,帮助读者更好地理解和掌握Map的使用技巧。 ### 一、Map简介 `Map`接口是Java集合框架的一部分,它提供了基于键值对的数据存储方式。常见的实现...
### Map集合的遍历 #### 一、概述 在Java编程语言中,`Map`接口是一种非常重要的数据结构,它存储的是键值对(Key-Value)的形式。`Map`集合的主要特点是每个元素都包含一个唯一的键(Key)以及与之对应的值...
集合总结及扩展1 本节内容总结了集合的继承体系、集合的接口、抽象类、具体类的概念,并详细介绍了Collection、Iterator、泛型、List、Set、Map等集合框架中的重要知识点。 1. 集合继承体系 集合继承体系中,接口...
根据给定文件的信息,我们可以详细地探讨一下Java中几种主要的集合容器——List、Set以及Map的区别,并且深入了解它们各自的特性和应用场景。 ### 一、List #### 1. ArrayList - **特点**:`ArrayList`是基于动态...
### Java集合框架总结 #### 一、Java集合框架概述 Java集合框架是Java标准库的一部分,它提供了一系列的接口和类来存储和操作各种类型的对象集合。这些接口和类遵循一致的设计模式,使得开发人员可以方便地管理和...
.Map集合的遍历方法 Map集合是Java中的一种常用的数据结构,用于存储键值对的数据。Map集合的遍历是指从Map集合中取出所有的键值对,并进行处理的过程。在实际开发中,Map集合的遍历是非常常见的操作。本文将介绍...
### Java中Map集合的用法详解 #### 一、引言 在Java编程语言中,`java.util`包内提供了多种强大的数据结构来帮助开发者高效地处理数据。其中,`Map`作为Java中最常用的数据结构之一,被广泛应用于各种场景。`Map`是...
#### 六、总结:集合框架中常用类比较 在选择合适的集合类时,需要考虑以下几个方面: - **性能需求**:是否需要快速访问、插入或删除? - **元素排序**:是否需要元素排序? - **元素重复性**:是否允许重复元素...
### Java中的集合总结一 #### 1. ArrayList **简介:** `ArrayList` 是 `List` 接口的一个实现类,它使用动态数组的方式存储数据。`ArrayList` 的特点是能够根据索引快速地访问列表中的元素,同时也支持通过索引...
Map集合是一种键值对集合,key不能重复,但是value可以重复。Map集合的主要实现类有HashMap、Hashtable、TreeMap等。HashMap是哈希表实现的,key不能重复,但是value可以重复。Hashtable是线程安全的,key和value不...