- 浏览: 285737 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
jim8757:
能提供下完整的代码吗?
实例解析java + jQuery + json工作过程(登录) -
befairy:
收藏,谢谢LZ
基于Java、jQuery应用的账务管理系统开源了(09.3.19更新) -
Gilbert_Sam:
我看过这本书,很好,看到二十几章的地方,结果网站就登陆不上,写 ...
Linux C编程一站式学习 http://learn.akae.cn/ -
ljy520zhiyong:
这个网址进入不了呀
Linux C编程一站式学习 http://learn.akae.cn/ -
蜀山红日:
如果后台要向前台返回复杂数据该怎么办呢
实例解析java + jQuery + json工作过程(登录)
HashMap map = new HashMap();
map.put("0201", "0201");
map.put("01", "01");
map.put("0304", "0304");
map.put("0101", "0101");
Object[] key = map.keySet().toArray();
Arrays.sort(key);
for (int i = 0; i < key.length; i++) {
System.out.println(map.get(key[i]));
}
-----------------------------------------------------------------------
Map hashMap = new HashMap();
List arrayList = new ArrayList(hashMap.entrySet());
Collections.sort(arrayList, new Comparator() {
public int compare(Object o1, Object o2) {
Map.Entry obj1 = (Map.Entry) o1;
Map.Entry obj2 = (Map.Entry) o2;
return (obj1.getKey()).toString().compareTo(obj2.getKey());
}
});
// 将HASHMAP中的数据排序-------------------------------------------
for (Iterator iter = arrayList.iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String)entry.getKey();
..........
}
--------------------------------------------------------------------------------------------------------
HashMap可谓JDK的一大实用工具,把各个Object映射起来,实现了“键--值”对应的快速存取。但实际里面做了些什么呢?
在这之前,先介绍一下负载因子和容量的属性。大家都知道其实一个 HashMap 的实际容量就 因子*容量,其默认值是 16×0.75=12; 这个很重要,对效率很一定影响!当存入HashMap的对象超过这个容量时,HashMap 就会重新构造存取表。这就是一个大问题,我后面慢慢介绍,反正,如果你已经知道你大概要存放多少个对象,最好设为该实际容量的能接受的数字。
两个关键的方法,put和get:
先有这样一个概念,HashMap是声明了 Map,Cloneable, Serializable 接口,和继承了 AbstractMap 类,里面的 Iterator 其实主要都是其内部类HashIterator 和其他几个 iterator 类实现,当然还有一个很重要的继承了Map.Entry 的 Entry 内部类,由于大家都有源代码,大家有兴趣可以看看这部分,我主要想说明的是 Entry 内部类。它包含了hash,value,key 和next 这四个属性,很重要。put的源码如下
public Object put(Object key, Object value) {
Object k = maskNull(key);
这个就是判断键值是否为空,并不很深奥,其实如果为空,它会返回一个static Object 作为键值,这就是为什么HashMap允许空键值的原因。
int hash = hash(k);
int i = indexFor(hash, table.length);
这连续的两步就是 HashMap 最牛的地方!研究完我都汗颜了,其中 hash 就是通过 key 这个Object的 hashcode 进行 hash,然后通过 indexFor 获得在Object table的索引值。
table???不要惊讶,其实HashMap也神不到哪里去,它就是用 table 来放的。最牛的就是用 hash 能正确的返回索引。其中的hash算法,我跟JDK的作者 Doug 联系过,他建议我看看《The art of programing vol3》可恨的是,我之前就一直在找,我都找不到,他这样一提,我就更加急了,可惜口袋空空啊!!!
不知道大家有没有留意 put 其实是一个有返回的方法,它会把相同键值的 put 覆盖掉并返回旧的值!如下方法彻底说明了 HashMap 的结构,其实就是一个表加上在相应位置的Entry的链表:
for (Entry e = table[i]; e != null; e = e.next) {
if (e.hash == hash && eq(k, e.key)) {
Object oldvalue = e.value;
e.value = value; //把新的值赋予给对应键值。
e.recordAccess(this); //空方法,留待实现
return oldvalue; //返回相同键值的对应的旧的值。
}
}
modCount++; //结构性更改的次数
addEntry(hash, k, value, i); //添加新元素,关键所在!
return null; //没有相同的键值返回
}
我们把关键的方法拿出来分析:
void addEntry(int hash, Object key, Object value, int bucketIndex) {
table[bucketIndex] = new Entry(hash, key, value, table[bucketIndex]);
因为 hash 的算法有可能令不同的键值有相同的hash码并有相同的table索引,如:key=“33”和key=Object g的hash都是-8901334,那它经过indexfor之后的索引一定都为i,这样在new的时候这个Entry的next就会指向这个原本的table[i],再有下一个也如此,形成一个链表,和put的循环对定e.next获得旧的值。到这里,HashMap的结构,大家也十分明白了吧?
所谓的重构也不神,就是建一个两倍大的table(我在别的论坛上看到有人说是两倍加1,把我骗了),然后再一个个indexfor进去!注意!!这就是效率!!如果你能让你的HashMap不需要重构那么多次,效率会大大提高!
说到这里也差不多了,get比put简单得多,大家,了解put,get也差不了多少了。对于collections我是认为,它是适合广泛的,当不完全适合特有的,如果大家的程序需要特殊的用途,自己写吧,其实很简单。(作者是这样跟我说的,他还建议我用LinkedHashMap,我看了源码以后发现,LinkHashMap其实就是继承HashMap的,然后override相应的方法,有兴趣的同人,自己looklook)建个 Object table,写相应的算法,就ok啦。
举个例子吧,像 Vector,list 啊什么的其实都很简单,最多就多了的同步的声明,其实如果要实现像Vector那种,插入,删除不多的,可以用一个Object table来实现,按索引存取,添加等。
如果插入,删除比较多的,可以建两个Object table,然后每个元素用含有next结构的,一个table存,如果要插入到i,但是i已经有元素,用next连起来,然后size++,并在另一个table记录其位置。
---------------------------------------------------------------------------------------------------------------------------------------------------------
Hashtable和HashMap的区别:
1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;而对于HashMap,则需要额外的同步机制。但HashMap的同步问题可通过Collections的一个静态方法得到解决:
Map Collections.synchronizedMap(Map m)
这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
3.在HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。当get()方法返回null值时,即可以表示HashMap中没有该键,也可以表示该键所对应的值为null。因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。
---------------------------------------------------------------------------------------------------------------------------------------------------------
4.1 HashMap 实例
- import java.util.*;
- public class ExampleHashMap {
- //calendar Map
- Map calendar = new HashMap();
- //constructor to add all elements into Map
- public ExampleHashMap(String d[], String i[]){
- for (int x=0; x<d.length; x++)
- calendar.put(d[x], i[x]);
- }
- //main method
- public static void main(String args[]) {
- //Data to be inserted into calendar
- String [] dates = {"10/31/01", "01/01/01", "03/05/01", "02/04/01"};
- String [] items = {"Halloween", "New Years", "Birthday", "Anniversary"};
- //create instance of class
- ExampleHashMap example = new ExampleHashMap(dates, items);
- //print out all key/value pairs in map
- System.out.println("map= " + example.calendar);
- //retrieve mappings into Set
- Set mappings = example.calendar.entrySet();
- System.out.println("object \t\t\tkey\t\tvalue");
- //iterate through mappings and print content
- for (Iterator i = mappings.iterator(); i.hasNext();) {
- Map.Entry me = (Map.Entry)i.next();
- Object ok = me.getKey();
- Object ov = me.getValue();
- System.out.print(me + "\t");
- System.out.print(ok + "\t");
- System.out.println(ov);
- }
- }
- }
- HashMap的输出 (不同的编译器会有不同顺序的输出):
[pre]/tmp> java ExampleHashMap
map= {01/01/01=New Years, 03/05/01=Birthday, 02/04/01=Anniversary, 10/31/01=Halloween}
object key value
01/01/01=New Years 01/01/01 New Years
03/05/01=Birthday 03/05/01 Birthday
02/04/01=Anniversary 02/04/01 Anniversary
10/31/01=Halloween 10/31/01 Halloween[/pre]
注意在HashMap对象存储既不是按照年代顺序,也不是按照字母顺序。输出的顺序其实是依赖于你选用了哪种编译器,以及机器的设置。实际上Halloween是第一个“put”到HashMap的,但是却存储在HashMap的最后。
4.2 TreeMap 实例
- import java.util.*;
- public class ExampleTreeMap {
- //calendar Map
- Map calendar = new TreeMap();
- //constructor to add all elements into Map
- public ExampleTreeMap(String d[], String i[]){
- for (int x=0; x<d.length; x++)
- calendar.put(d[x], i[x]);
- }
- //main method
- public static void main(String args[]) {
- //Data to be inserted into calendar
- String [] dates = {"10/31/01", "01/01/01", "03/05/01", "02/04/01"};
- String [] items = {"Halloween", "New Years", "Birthday", "Anniversary"};
- //create instance of class
- ExampleTreeMap example = new ExampleTreeMap(dates, items);
- //print out all key/value pairs in map
- System.out.println("map= " + example.calendar);
- //retrieve mappings into Set
- Set mappings = example.calendar.entrySet();
- System.out.println("object \t\t\tkey\t\tvalue");
- //iterate through mappings and print content
- for (Iterator i = mappings.iterator(); i.hasNext();) {
- Map.Entry me = (Map.Entry)i.next();
- Object ok = me.getKey();
- Object ov = me.getValue();
- System.out.print(me + "\t");
- System.out.print(ok + "\t");
- System.out.println(ov);
- }
- }
- }
- TreeMap的输出:
[pre]/tmp> java ExampleTreeMap
map= {01/01/01=New Years, 02/04/01=Anniversary, 03/05/01=Birthday, 10/31/01=Halloween}
object key value
01/01/01=New Years 01/01/01 New Years
02/04/01=Anniversary 02/04/01 Anniversary
03/05/01=Birthday 03/05/01 Birthday
10/31/01=Halloween 10/31/01 Halloween[/pre]
TreeMap的输出比HashMap更加具有可预言性。注意在TreeMap中映射以关键字的字母顺序存储。不同于HashMap的输出,在一个实际的世界日历程序中,TreeMap的输出将更加有用。正如前面提及的,使用TreeMap数据结构的一个缺点是,当你在TreeMap结构中“put”或“remove”元素时,因为需要排序从而需要一些开销,这会影响到程序的性能。(译注:可以先使用HashMap,在需要顺序输出时,通过把HashMap对象作为参数传入,构造一个TreeMap达到高性能同时满足排序的双重目的)。
发表评论
-
自定义js延时函数
2010-03-26 11:38 4547setTimeout不是真正意义上的延时函数,而且在表单提交后 ... -
ssh jar包配置
2009-11-27 11:31 2314本文中ssh指:struts2,srping2.5,hib ... -
每个项目中,你不得不知的11个Java第三方类库
2009-11-02 09:06 1119Java第三方library ecosystem是一个很广阔的 ... -
J2EE学习中一些值得研究的开源项目
2009-08-10 10:07 1175这篇文章写在我研究J2SE、J2EE近三年后。前3年 ... -
对JXL包的研究(java操作excel)
2009-06-25 07:44 1544对JXL包的研究(java操作excel) 在开源世界中,有两 ... -
java类中成员的装载顺序你知道吗
2009-04-03 08:18 1006最近去参加了SCJP培训,相信对于绝大多数的JAVA工作者来说 ... -
java操作word文件
2009-03-31 15:41 1732一个jacob操作Word的例子 import java. ... -
Java操作PDF文件(iText)
2009-03-31 15:32 5903然jacob中也有关于PDF的方法,但是过于复杂。iText是 ... -
java对excel操作
2009-03-31 15:11 1475从Excel文件读取数据表 Java Excel API既可 ... -
JAVA解析XML的四种方法
2009-03-31 08:49 1418XML现在已经成为一种通 ... -
Java:集合类性能分析
2009-03-20 20:41 19661.Java 集合框架图 -集合接口:6个接口(短虚 ... -
在看commons-lang.jar包源码时候的一些发现及实践
2009-03-11 10:55 3633通常,我们在完成一个标准的JavaBean的时候,都需要同时完 ... -
解决大批量数据导出Excel产生内存溢出的方案(二)
2009-03-11 10:42 6335客户要求一次导出20w行数据,这就要求导出的文件必须带shee ... -
解决大批量数据导出Excel产生内存溢出的方案
2009-03-11 10:41 5421POI或者JXL在导出大量数据的时候,由于它们将每一个单元格生 ... -
java语言的反射机制1
2009-03-11 10:23 1129java语言的反射机制为是java语言所提供的一项特别吸引人的 ... -
Java获取各种常用时间方法(二)
2009-03-11 09:43 1071//获得本年最后一天的日期 * ... -
Java获取各种常用时间方法
2009-03-11 09:40 1219本人之前做的项目中积累常用的时间方法,贴出来与大家共享,如果哪 ... -
JavaSE6.0 Web Service学习笔记(二)
2009-03-11 09:30 7411JavaSE6.0下的Web Service 从JavaSE6 ... -
JavaSE6.0 Web Service学习笔记(一)
2009-03-11 09:24 1442Web Service概述 Web Service ... -
JDK5.0 Annotation学习笔记(一)
2009-03-11 09:22 972背景知识: 从JDK5开始提供名为Annotat ...
相关推荐
接下来,示例代码还提供了一种按值排序`HashMap`的方法。这种方法利用了自定义比较器`ByValueComparator`。具体步骤如下: 1. **定义比较器**:定义一个名为`ByValueComparator`的类,该类实现了`Comparator...
在某些场景下,我们可能需要对HashMap进行排序,例如按照key的值或key的自然顺序进行排序。本文将详细介绍如何对HashMap进行排序以及相关的知识点。 **1. HashMap的特点** HashMap的核心特点是其内部通过哈希函数来...
最后,我们遍历排序后的entrySet,打印出键值对,此时的值是按降序排列的。 通过这样的方式,我们可以实现对HashMap值的排序,但请注意,这并不改变原HashMap的结构,只是生成了一个排序后的视图。如果需要在...
"对 Map 按 key 和 value 分别排序" 摘要:本文主要介绍了 Map 按 key 和 value 分别排序的方法,包括使用 TreeMap 的 key 排序和 value 排序两种方式。 Map 按 key 排序 Map 是键值对的集合接口,它的实现类主要...
先根据value的值从小到大排序,value相同再根据key的字母顺序来排序
Java HashMap两种简便排序方法解析 Java HashMap是一种常用的数据结构,然而,它的储存是没有顺序的,按照key的HashCode实现。这使得在 certainsituations下的排序变得非常重要。下面,我们将介绍两种简便的排序...
本篇文章将深入讲解如何在Java中实现Map按Key排序,并通过一个具体的实例代码进行演示。 首先,我们要了解Java中支持按Key排序的Map实现类:TreeMap。TreeMap内部基于红黑树数据结构,能够保证Map的Key按照自然顺序...
当需要对Map中的数据进行排序时,通常有两种情况:按key排序和按value排序。本文将详细介绍如何在Android环境下对Map进行这两种排序。 首先,我们来讨论按key排序。TreeMap是一个基于红黑树实现的Map,它可以根据...
标题中提到的“JCF(List、Set、Map)学习,实现了<key,value>按value排序”是一个关键点,我们将深入探讨这个话题。 首先,让我们了解List、Set和Map的区别。List是有序的集合,允许重复元素,并且可以保持插入顺序...
Java8 Stream 操作 Map 根据 Key 或 Value 排序的实现 Java8 中的 Stream 操作为开发者提供了简洁高效的数据处理方式,今天我们将介绍如何使用 Java8 Stream 操作 Map 根据 Key 或 Value 排序的实现。 Map 根据 ...
在Android开发中,我们经常会遇到需要对HashMap进行排序的需求,特别是在处理数据展示或者数据分析时。HashMap本身不保证元素的顺序,但我们可以采用一些方法来实现排序。本文将详细介绍如何在Android中实现HashMap...
1. **Key排序**: - **TreeMap** 是一个基于红黑树数据结构的Map实现,它能自动按key的自然顺序或自定义的Comparator进行排序。默认情况下,TreeMap会按照key的自然顺序进行升序排序。 - 要实现自定义排序,可以...
HashMap不保证元素的顺序,如果需要保持插入顺序或根据特定规则排序,应考虑使用LinkedHashMap。 ArrayList和HashMap的使用场景有所不同。ArrayList适合于需要频繁进行随机访问且元素顺序重要的情况,比如作为数据...
`ordered-map`,正如其名,是一个按值排序的HashMap。在传统的HashMap中,元素的位置是不确定的,因为它们的存储基于哈希函数的结果,这通常会导致元素在内存中的随机分布。然而,`ordered-map`提供了一种按特定顺序...
在这个"用HashMap写的一个小Demo用来写游戏排名的一种方法"的示例中,我们很可能会看到如何利用HashMap来组织游戏分数并进行排序,以实现一个简单的游戏排名系统。 HashMap的特点在于它的键(key)是唯一的,每个键...
在Java编程语言中,HashMap是一种常用的集合类,它实现了Map接口,用于存储键值对...此外,了解HashMap内部结构也有助于选择更适合特定场景的其他数据结构,如TreeMap(按键排序)或ConcurrentHashMap(线程安全)。
与`HashTable`相比,`HashMap`最大的不同之处在于它允许`key`和`value`为`null`。 **特点:** - **线程安全性**:`HashMap`不是线程安全的,如果多个线程同时访问,必须在外部进行同步控制。 - **null的支持**:`...
Node[] table是HashMap的核心,它是一个Node数组,数组的每一个元素都是一个Node对象,每个Node对象可以包含一个key-value键值对。Node是HashMap的内部类,它实现了Map.Entry,V>接口。 HashMap的扩容机制在JDK 1.8...
HashMap是Java集合框架的一部分,位于`java.util`包下,实现了Map接口,用于存储键值对(key-value pairs)。在深入理解HashMap之前,我们先简单回顾一下Java集合的基本概念。 Java集合框架包括Set、List和Map三个...