Java集合四大家族的故事(四)——Map家族的LinkedHashMap

每个家族都有一个最基本且最常用的数据类型:比如List系列的ArrayList,Map系列的HashMap,并且,它们的本质都是数组存储结构。相似的是,每个家族都有一个Linked开头的类,如List家族的LinkedList和Map家族的LinkedHashMap,这两个类的存储的数据结构又都是双向链表(其实是连续数组添加了两个方向的指针,所以既能与数组兼容,又能够有双向链表的性质)。而引入双向链表功能的目的就是为了能够有序遍历。

今天,我们就来介绍LinkedHashMap。

扩展HashMap增加双向链表的实现,号称是最占内存的数据结构。支持iterator()时按Entry的插入顺序来排序(但是更新不算, 如果设置accessOrder属性为true,则所有读写访问都算)。

实现上是在Entry上再增加属性before/after指针,插入时把自己加到Header Entry的前面去。如果所有读写访问都要排序,还要把前后Entry的before/after拼接起来以在链表中删除掉自己。

(本文出自:http://my.oschina.net/happyBKs/blog/493260)

下面的例子,我没对LinkedHashMap和HashMap分别做了两组比较,数据两组分别一一对应。

我们可以发现,LinkedHashMap返回的key-value的顺序,与我们插入put的顺序一致,插入的顺序不同,返回的顺序也不同。而HashMap无论我们按照什么顺序插入,返回的顺序都是唯一的,且与插入顺序无关,HashMap的返回key-value的顺序只与hashCode有关。

	@Test
	public void testLinkedHashMap(){
		System.out.println("LinkedHashMap: N-M-S");
		LinkedHashMap<String,Integer> lhm=new LinkedHashMap<String,Integer>();
		lhm.put("NOKIA", 4000);
		lhm.put("MOTO", 3000);
		lhm.put("SAMGSUNG", 3500);

		for(Entry e:lhm.entrySet()){
			System.out.println(e.getKey()+": "+e.getValue());
		}

		System.out.println("LinkedHashMap: S-N-M");
		LinkedHashMap<String,Integer> lhm2=new LinkedHashMap<String,Integer>();
		lhm2.put("SAMGSUNG", 3500);
		lhm2.put("NOKIA", 4000);
		lhm2.put("MOTO", 3000);

		for(Entry e:lhm2.entrySet()){
			System.out.println(e.getKey()+": "+e.getValue());
		}

		System.out.println("HashMap: N-M-S");
		HashMap<String,Integer> hm=new HashMap<String,Integer>();
		hm.put("NOKIA", 4000);
		hm.put("MOTO", 3000);
		hm.put("SAMGSUNG", 3500);

		for(Entry e:hm.entrySet()){
			System.out.println(e.getKey()+": "+e.getValue());
		}

		System.out.println("HashMap: S-N-M");
		HashMap<String,Integer> hm2=new HashMap<String,Integer>();
		hm2.put("SAMGSUNG", 3500);
		hm2.put("NOKIA", 4000);
		hm2.put("MOTO", 3000);

		for(Entry e:hm2.entrySet()){
			System.out.println(e.getKey()+": "+e.getValue());
		}

/*		LinkedHashMap: N-M-S
		NOKIA: 4000
		MOTO: 3000
		SAMGSUNG: 3500
		LinkedHashMap: S-N-M
		SAMGSUNG: 3500
		NOKIA: 4000
		MOTO: 3000
		HashMap: N-M-S
		MOTO: 3000
		NOKIA: 4000
		SAMGSUNG: 3500
		HashMap: S-N-M
		MOTO: 3000
		NOKIA: 4000
		SAMGSUNG: 3500*/
		//HashMap插入的键值对是无序的,位置只与key关联;LinkedHashMap与插入顺序相关
		//实际上LinkedHashMap是在Entry上再增加属性before/after指针,
		//插入时把自己加到Header Entry的前面去。
		//如果所有读写访问都要排序,还要把前后Entry的before/after拼接起来以在链表中删除掉自己。

	}
时间: 2024-12-09 00:46:46

Java集合四大家族的故事(四)——Map家族的LinkedHashMap的相关文章

Java集合框架总结(5)——Map接口的使用

Java集合框架总结(5)--Map接口的使用 Map用于保存具有映射关系的数据(key-vlaue).Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较总是返回false Map中包含了一个keySet()方法,用于返回Map所以key组成的Set集合. Map集合与Set集合元素的存储形式很像,如Set接口下有HashSet.LinkedHashSet.SortedSet(接口).TreeSet.EnumSet等实现类和子接口,而Map接口下则有HashMa

Java集合框架--List、Set、Map

Java集合框架接口和类的层次结构: java.util.Collection [I] +--java.util.List [I] +--java.util.ArrayList [C] +--java.util.LinkedList [C] +--java.util.Vector [C] +--java.util.Stack [C] +--java.util.Set [I] +--java.util.HashSet [C] +--java.util.SortedSet [I] +--java.u

Java集合源码分析(四)Vector&lt;E&gt;

Vector<E>简介 Vector也是基于数组实现的,是一个动态数组,其容量能自动增长. Vector是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全),可以用于多线程环境. Vector没有丝线Serializable接口,因此它不支持序列化,实现了Cloneable接口,能被克隆,实现了RandomAccess接口,支持快速随机访问. Vector<E>源码 如下(已加入详细注释): /*

Java集合研究一:Set与Map

Set代表一种无序集合,集合元素不可重复:Map代表一种多个key-value对组成的集合 从Set和Map的继承体系图看,如果从名称分析,Set和Map有着千丝万缕的联系.并且从JDK中提供的Map接口中,你会发现提供了这样一个方法: Set<K> keySet();这就说明了,如果抛开Map中的value,那么Map中的所有key的实际上就是一个Set集合,而且我们查询的时候常常是通过key来查找value,那么我们可以将value和key绑定在一起,将value看成是key的附属物,那么

Java集合:List、Set和Map的区别,ArrayList和LinkedList有何区别..........

一.数组和集合的区别: 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型): 集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. 数组和集合相比唯一的有点就是速度快. 二.Java集合分类: 1.Collection(接口):派生的两个子接口:List和Set List(列表):有序.可重复元素,可以插入多个null元素.实现List接口的常用类有LinkedList

Java集合框架源码(四)——Vector

第1部分 Vector介绍 Vector简介 Vector 是矢量队列,它是JDK1.0版本添加的类.继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口.Vector 继承了AbstractList,实现了List:所以,它是一个队列,支持相关的添加.删除.修改.遍历等功能.Vector 实现了RandmoAccess接口,即提供了随机访问功能.RandmoAccess是java中用来被List实现,为List提供快速访问功能的.在Vecto

java集合: List、Set、Map总结 + HashMap/Hashtable 差别

List:(有序,能够反复)通过下标索引 ----ArrayList  可变数组,随机查找 ----LinkedList    链表,不论什么位置插入删除快 ----Vector    效率比arraylist低.可是能够用于多线程同步 Set:(无序,不能够反复)set最多有一个null元素.由于不能够反复 ----HashSet    没有排序,不反复(顺序随机) ----LinkedHashSet    按插入排序.不反复(按插入顺序) ----TreeSet    实现Comparabl

java 集合(list、set、map)的特点

集合相关的类有一大堆,一般也只用到常用的方法增删改查,而且它它们的方法名也基本一样,所以一直都不知道什么时候用什么集合, 今天趁有空特意从网上整理资料方便日后回忆. 一.List:.有顺序以线性方式存储,可以存放重复对象 线程安全方法:List list = Collections.synchronizedList(new LinkedList(...)); LinkedList:双向链表实现存储 索引数据慢插入数度较快 线程不安全(比安全性能好) ArrayList:数组方式存储数据 索引数据

Java集合总结(二):Map和Set

集合类的架构图: HashMap 内部维护一个链表数组做哈希表,默认大小为16,最大值可以为2^30,默认负载因子0.75. 可以通过构造方法指定初始大小和负载因子,当键值对个数大于等于临界值threshold(数组当前大小和负载因子的乘积)时对数组进行扩容,扩容策略为当前数组大小乘以2. 数组的每一项都是一个链表,链表的每个结点(静态内部类Entry)都是键值对,并缓存了key的hash值. key 和value都可以为null,key为null时结点存储在hash表数组下标为0的位置. pu