- 浏览: 296645 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (176)
- Algorithm (4)
- Diary (9)
- GIS-RS-GPS (15)
- Hibernate (1)
- JavaSE (4)
- 其他开源 (0)
- 架构与设计 (4)
- Web 客户端技术 (21)
- Web 框架与开发 (6)
- ArcEngine 开发 (2)
- ArcGIS Server 开发 (0)
- ArcIMS 开发 (3)
- 空间数据库 (0)
- Eclipse Plugin (1)
- Eclipse Framework (0)
- GIS-GPS-RS (0)
- [网站分类]1.网站首页原创Java技术区(对首页文章的要求: 原创、高质量、经过认真思考并精心写作。BlogJava管理团队会对首页的文章进行管理。) (54)
- [网站分类]2.Java新手区 (10)
- [网站分类]3.非技术区 (8)
- [网站分类]4.其他技术区 (19)
- [网站分类]6.转载区(Java技术文章转载, 请注明原文出处) (8)
最新评论
-
wen0301:
认同! 程序员必须锻炼内功,而不是华丽的花拳绣腿。
Google的Offer -
leelight:
我用了凸角圆弧法,发现此算法在半径相对较大时,输入结果经常是一 ...
GIS 缓冲区应用及算法实现 -
palmer:
据说 Google 有中国本地的服务器.有没有这方面的原因?? ...
地震为什么没有影响到 Google -
chxkyy:
跑getShapefileFeatureClass方法
AE92 SDK for Java 最小示例学习 -
chxkyy:
我在本地跑这个代码怎么报这个错:java.lang.Unsat ...
AE92 SDK for Java 最小示例学习
Java容器分析--Map
作者:Flyingis
标准的Java类库中包含了几种类型的Map,它们都拥有同样的基本接口Map,但是行为特性各不相同,主要表现在效率、键值对的保存、元素呈现次序、对象的保存周期和判定键是否等价的策略等方面。<!----><o:p></o:p>
1.Map的功能方法<o:p></o:p>
Map(interface): 维护label和value的关联性,使得可以通过label查找value。<o:p></o:p>
HashMap: Map基于散列表的实现,取代了Hashtable。插入和查询label/value的开销是固定的,并且可以通过构造器设置容量和负载因子,以调整容器的性能。<o:p></o:p>
LinkedHashMap: 在HashMap的基础上做了一些改进,在迭代遍历它时,取得label/value的顺序是其插入的次序,或者是最近最少使用(LRU)的次序,速度上比HashMap要慢一点,但在迭代访问时速度会更快,主要原因是它使用了链表维护内部次序。<o:p></o:p>
TreeMap: 查看label或label/value时,元素会被排序,其次序由Comparable或Comparator决定,因此查询所得到的结果是经过排序的。另外,它是唯一带有subMap()方法的Map具体类,即返回一个子树。它也是SortedMap接口的唯一实现,subMap()方法也是从该接口继承的。<o:p></o:p>
WeakHashMap: Weak Key映射,允许释放映射所指向的对象。当映射之外没有引用指向某个label时,此label可以被垃圾收集器回收。<o:p></o:p>
IdentityHashMap: 使用==代替equals()对label进行比较的散列映射。<o:p></o:p>
2.hashCode()<o:p></o:p>
当使用标准库中的类Integer作为HashMap的label时,程序能够正常运行,但是使用自己创建的类作为HashMap的label时,通常犯一个错误。<o:p></o:p>
在HashMap中通过label查找value时,实际上是计算label对象地址的散列码来确定value的。一般情况下,我们是使用基类Object的方法hashCode()来生成散列码,它默认是使用对象的地址来计算的,因此由第一个对象new Apple(5)和第二个对象new Apple(5)生成的散列码是不同的,不能完成正确的查找。通常,我们可以编写自己的hashCode()方法来覆盖基类的原始方法,但与此同时,我们必须同时实现equals()方法来判断当前的label是否与表中存在的label相同。正确的equals()方法满足五个条件:<o:p></o:p>
(1) 自反性。对于任意的x,x.equals(x)一定返回true。<o:p></o:p>
(2) 对称性。对于任意的x和y,如果y.equals(x)返回true,则x.equals(y)也返回true。<o:p></o:p>
(3) 传递性。对于任意的x、y、z,如果有x.equals(y)返回true,y.equals(z)返回true,则x.equals(z)一定返回true。<o:p></o:p>
(4) 一致性。对于任意的x和y,如果对象中用于等价比较的信息没有改变,那么无论调用x.equals(y)多少次,返回的结果应该保持一致,要么一直是true,要么一直是false。<o:p></o:p>
(5) 对任何不是null的x,x.equals(null)一定返回false。<o:p></o:p>
equals()比较的是对象的地址,如果要使用自己的类作为HashMap的label,必须同时重载hashCode()和equals()方法。<o:p></o:p>
使用散列的目的:想要使用一个对象来查找另一个对象。使用TreeSet或TreeMap也能实现此目的。另外,还可以自己实现一个Map,此时,必须提供Map.entrySet()方法来生成Map.Entry对象的Set。<o:p></o:p>
使用散列的价值:速度,散列使得查询可以快速进行。散列将label保存载数组中方便快速查询,因为存储一组元素最快的数据结构是数组,用它来表示label的信息(后面有信息的描述),而不是label本身。通过label对象计算得到一个数字,作为数组的下标,这个数字就是散列码(即前面所述的信息)。该散列码具体是通过定义在基类Object中,可能由程序员自定义的类覆盖的hashCode()方法,即散列函数生成。为了解决数组容量带来的限制,可以使不同的label生成相同的下标,保存在一个链表list中,每一个链表就是数组的一个元素。查询label时就可以通过对list中的信息进行查找,当散列函数比较好,数组的每个位置中的list长度较短,则可以快速查找到数组元素list中的某个位置,提高了整体速度。<o:p></o:p>
散列表中的slot通常称为bucket,为了使散列分步均匀,bucket的值一般取质数。但事实证明,质数实际上并不是散列bucket的理想容量,近来Java散列实现都使用2的幂,具体如何验证以后再续。<o:p></o:p>
3.HashMap的性能因子<o:p></o:p>
容量(capacity): 散列表中bucket的数量。<o:p></o:p>
初始化容量(initial capacity): 创建散列表时bucket的数量。可以在构造方法中指定HashMap和HashSet的初始化容量。<o:p></o:p>
尺寸(size): 散列表中记录的数量。(数组的元素个数,非list中元素总和)<o:p></o:p>
负载因子(load factor): 尺寸/容量。负载因子为0,表示空的散列表,0.5表示半满的散列表。轻负载的散列表具有冲突少,适宜插入与查询的特点,但是使用迭代器遍历会比较慢。较高的负载会减少所需空间大小。当负载达到指定值时,容器会自动成倍地增加容量,并将原有的对象重新分配,存入新的bucket中,这个过程称为“重散列”。<o:p></o:p>
4.重写hashCode()的关键<o:p></o:p>
(1) 对同一个对象调用hashCode()都应该生成同样的值。<o:p></o:p>
(2) hashCode()方法不要依赖于对象中易变的数据,当数据发生变化时,hashCode()就会生成一个不同的散列码,即产生了一个不同的label。<o:p></o:p>
(3) hashCode()不应依赖于具有唯一性的对象信息,例如对象地址。<o:p></o:p>
(4) 散列码应该更关心速度,而不是唯一性,因为散列码不必是唯一的。<o:p></o:p>
(5) 好的hashCode()应该产生分步均匀的散列码。在Effective Java(Addison-Wesley 2001)中,Joshua Bloch给hashCode()给出了设计指导,可以参考。<o:p></o:p>
编写正确高效的hashCode()和equals()可以参考Apache的Jakarta Commons项目中的工具。其它相关内容:
Java容器分析--数组
Java容器分析--List和Set
发表评论
-
小议final关键字
2005-10-28 21:50 1767作者:Flyingis final是Java语言中一 ... -
多态学习心得
2005-10-31 19:28 1266作者:Flyingis 这几天我在重新复习Java语言基 ... -
Java接口特性学习
2005-11-02 21:18 1175作者:Flyingis 在Jav ... -
理解Java内部类的基本特性(一)
2005-11-04 17:11 1417作者:Flyingis 内部类是Java语言一个 ... -
理解Java内部类的基本特性(二)
2005-11-04 18:55 1289作者:Flyingis4. 内部类拥有其外围类的所有元素的访 ... -
JSF VS Tapestry 全面比较
2005-11-09 13:08 1241作者:Flyingis Java不像微软拥有Vi ... -
Hibernate学习心得--性能优化
2005-11-15 10:22 1329作者:Flyingis 在使用Hiber ... -
Struts Action的多种角色
2005-11-18 17:10 1243作者:Flyingis ... -
中国企业对软件人才利用的思考
2005-11-21 14:08 1164作者:Flyingis 刚刚看到一篇文章《中方落 ... -
关键字new和newInstance方法区别
2005-12-03 16:48 1200作者:Flyingis 在初始化一个类,生成一个 ... -
Google的Offer
2005-12-07 15:05 1297作者:Flyingis 昨 ... -
Google新服务--出行路线规划服务
2005-12-09 20:04 1504作者: ... -
浅议类型识别与反射机制
2005-12-11 14:43 980作者:Flyingis 运行时类型识别(Run- ... -
ClassCastException深入分析
2005-12-18 18:57 1190作者:Flyingis ClassCastExcep ... -
热点讨论--"Java? It's So Nineties"
2005-12-18 19:32 919作者:Flyingis贴一则消息。今天在各大网站上都 ... -
Java容器分析--List和Set
2005-12-21 15:06 821作者:Flyingis 容器类可以大大提高编程 ... -
GIS数据建库基本思想(上)
2005-12-22 18:43 1226地理信息系统的建设中,数据库的建设极为重要,基础地形 ... -
GIS数据建库基本思想(下)
2005-12-25 15:24 1330GIS数据建库基本思想(上) ... -
Java I/O中的设计模式
2005-12-30 21:47 986作者:Flyingis 任何程序语言的I/O设计都是一项 ... -
2006年的 Java IDE
2006-01-05 20:51 685作者: Flyingi ...
相关推荐
Java容器学习笔记: 容器概览, 容器中的设计模式, 容器源码分析 - List, 容器源码分析 - Map, 容器源码分析 - 并发容 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,...
此java类实现了对数据表的分类递归树的实现,为本人倾力之作,后期,会发布js版,敬请期待!
总结来说,深入理解Java内存模型对于正确实现并发容器如`concurrentMap`至关重要。通过分析HotCode,我们可以找出并优化性能关键点。同时,熟悉`HashMap`的底层机制和使用注解技术可以增强代码的并发安全性。而了解...
此外,容器和集合框架是Java编程中不可或缺的部分。ArrayList、LinkedList、HashMap等集合类提供了数据存储和操作的便利。同时,接口(如Comparator、Iterable)和设计模式(如工厂模式、单例模式)也是高级Java...
通过这些练习,你将巩固对Java容器的理解,提高代码编写效率,并为解决实际问题打下坚实基础。记得在实践中不断挑战自己,尝试不同的场景和数据结构,以便更好地掌握Java容器的精髓。祝你在学习过程中取得优异的成绩...
- **变量**:在Java中,变量是存储数据的容器,分为基本类型(如int, double, boolean等)和引用类型(如类、接口、数组)。 - **数据类型**:Java有两大类数据类型,即原始类型(primitives)和引用类型...
OpenJDK是Java Development Kit(JDK)的一个实现,它提供了Java语言的编译器、调试器、性能分析工具以及运行时环境。这个特定的版本针对的是AMD64处理器架构,也被称为x86_64或x64架构,广泛应用于Linux操作系统。 ...
- **并发容器**:如ConcurrentHashMap、BlockingQueue、ThreadPoolExecutor等在多线程环境下的应用。 4. **内存模型与垃圾回收** - **JVM内存结构**:堆、栈、方法区、本地方法栈等区域的划分和作用。 - **垃圾...
Java容器主要分为两大类:Collection和Map。 Collection Collection是一个独立元素的序列,这些元素都服从一条或多条规则。Collection接口提供了基本的操作方法,例如add、remove、contains等。 List List是一个...
Tomcat是Apache软件基金会的开源Java Servlet容器,用于运行Java Web应用程序,包括JSP和Servlet。在部署Geoserver时,我们需要将`geoserver.war`文件放到Tomcat的`webapps`目录下,Tomcat会自动解压并运行这个WAR...
### Java容器学习心得详解 在Java编程中,容器(Containers)是存储和操作对象集合的重要工具,主要包括集合(Collections)和映射(Maps)。本文将深入解析Java容器的关键概念、特性以及不同容器类型的应用场景。 ...
5. **Optional类**:为了解决空指针异常问题,Java 8引入了`Optional`类,它是一个容器对象,可能包含或不包含非null值。这有助于开发者编写更清晰、更安全的代码,避免出现`NullPointerException`。 6. ** Nashorn...
这些知识点仅仅是Java容器对象的一部分,实际的博客可能会包含更多细节,如源码分析、性能对比和最佳实践。通过阅读博客中的`持有对象.xmind`文件,可以进一步了解博主对这些概念的详细整理和分类。如果你对Java容器...
此外,Java集合框架是另一个关键部分,包括List、Set和Map接口,以及ArrayList、LinkedList、HashSet、HashMap等实现。这些集合类提供了存储和操作对象的方式。 在面向对象编程方面,你会学习类的定义、继承、封装...
8. **集合框架**:Java集合框架包括List、Set、Map等接口和ArrayList、LinkedList、HashSet、HashMap等实现类。它们提供了存储和操作对象的容器,是Java编程中不可或缺的一部分。 9. **输入/输出流**:Java的IO流...
Java容器源码分析 在Java编程中,容器是管理和组织对象的重要工具,它们提供了一种方式来存储和操作一组相关的对象。本项目"Java-basic-notes-sourcecode"包含了学习Java基础知识时涉及的一些源代码示例,涵盖了从...
JAVA容器的概述,List,Map,Set
6. **类型安全的异构容器(Collections Framework Enhancements)**:对集合框架进行了增强,如加入了`List`, `Set`, `Map`接口的`addAll()`、`containsAll()`、`removeAll()`和`retainAll()`方法,以及`Collections...