hashmap,hashset
来源:互联网 发布:什么精华液比较好知乎 编辑:程序博客网 时间:2024/05/17 06:21
要知道hashmap是什么,首先要搞清楚它的数据结构,在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,hashmap也不例外。Hashmap实际上是一个数组和链表的结合体(在数据结构中,一般称之为“链表散列“),请看下图(横排表示数组,纵排表示数组元素【实际上是一个链表】)。
从图中我们可以看到一个hashmap就是一个数组结构,当新建一个hashmap的时候,就会初始化一个数组。我们来看看java代码:
- /**
- * The table, resized as necessary. Length MUST Always be a power of two.
- * FIXME 这里需要注意这句话,至于原因后面会讲到
- */
- transient Entry[] table;
- static class Entry<K,V> implements Map.Entry<K,V> {
- final K key;
- V value;
- final int hash;
- Entry<K,V> next;
- ..........
- }
上面的Entry就是数组中的元素,它持有一个指向下一个元素的引用,这就构成了链表。
当我们往hashmap中put元素的时候,先根据key的hash值得到这个元素在数组中的位置(即下标,一般情况是通过hash(key)%len获得),然后就可以把这个元素放到对应的位置中了。如果这个元素所在的位子上已经存放有其他元素了(hash冲突),那么在同一个位子上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。从hashmap中get元素时,首先计算key的hashcode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。从这里我们可以想象得到,如果每个位置上的链表只有一个元素,那么hashmap的get效率将是最高的,但是理想总是美好的,现实总是有困难需要我们去克服,哈哈~
从hashmap中取元素时,get方法首先计算key的hashcode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。所以,hashcode与equals方法对于找到对应元素是两个关键方法。
Hashmap的key可以是任何类型的对象,例如User这种对象,为了保证两个具有相同属性的user的hashcode相同,我们就需要改写hashcode方法,比方把hashcode值的计算与User对象的id关联起来,那么只要user对象拥有相同id,那么他们的hashcode也能保持一致了,这样就可以找到在hashmap数组中的位置了。如果这个位置上有多个元素,还需要用key的equals方法在对应位置的链表中找到需要的元素,所以只改写了hashcode方法是不够的,equals方法也是需要改写滴
使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
默认的equals()方法只有两个引用都是引用同一个对象的时候才是true(跟“==“一样)
- Cat c1 = new Cat(1, 2, 3);
- Cat c2 = new Cat(1, 2, 6);
- System.out.println(c1 == c2); //false
- System.out.println(c1.equals(c2)); //false
- String s1 = new String("hello");
- String s2 = new String("hello");
- String m1 = "hello";
- String m2 = "hello";
- System.out.println(s1 == s2); //false
- System.out.println(m1 == m2); //true
- System.out.println(s1.equals(s2)); //true ,如果没有重写equals方法,也是false
- //实体类
- class Cat {
- int color;
- int height, weight;
- public Cat(int color, int height, int weight) {
- this.color = color;
- this.height = height;
- this.weight = weight;
- }
- //重写equals方法
- public boolean equals(Object obj) {
- if(obj == null) return false;
- else {
- if(obj instanceof Cat) {
- Cat c = (Cat)obj;
- if(c.color == this.color && c.height
- == this.height && c.weight == this.weight) {
- return true;
- }
- }
- }
- return false;
- }
- }
hashset:
1.HashSet概述:
HashSet实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。HashSet中不允许有重复元素,这是因为HashSet是基于HashMap实现的,HashSet中的元素都存放在HashMap的key上面,而value中的值都是统一的一个private static final Object PRESENT = new Object();。HashSet跟HashMap一样,都是一个存放链表的数组。
HashSet中add方法调用的是底层HashMap中的put()方法,而如果是在HashMap中调用put,首先会判断key是否存在,如果key存在则修改value值,如果key不存在这插入这个key-value。而在set中,因为value值没有用,也就不存在修改value值的说法,因此往HashSet中添加元素,首先判断元素(也就是key)是否存在,如果不存在这插入,如果存在着不插入,这样HashSet中就不存在重复值。
2.HashSet的实现:
对于HashSet而言,它是基于HashMap实现的,HashSet底层使用HashMap来保存所有元素,更确切的说,HashSet中的元素,只是存放在了底层HashMap的key上, 而value使用一个static final的Object对象标识。因此HashSet 的实现比较简单,相关HashSet的操作,基本上都是直接调用底层HashMap的相关方法来完成
第一:HashSet的构造和增加元素
集合中存放的是对象的引用。集合中元素的存储空间是自动开辟的,不像数组需要预先开辟内存。
HashSet hashSet = new HashSet();
hashSet.add(new Integer(1)); //向集合中添加一个整数
hashSet.add("a"); //向集合中添加一个字符串
int x[] = {1,2,3,4,5};
hashSet.add(x); //向集合中添加一个数组
Person p = new Person("张三", 23, "男", "研究生");
hashSet.add(p); //向集合中添加一个自定义类的对象
第二:HashSet的遍历
所谓遍历就是按照某种顺序,对于集合中的每个元素访问一次并且仅一次,不重复也不遗漏。
Iterator it = hashSet.iterator();
while(it.hasNext()){
Object obj = it.next();
if(obj instanceof Integer){
System.out.println("integer:"+obj);
}
if(obj instanceof String){
System.out.println("String:"+obj);
}
if(obj instanceof int[]){
System.out.println("integer:"+x[4]);
}
if(obj instanceof Person){
System.out.println("Person:"+p.getName()+p.getAge()+p.getSex()+p.getEducation());
}
}
输出结果是:
integer:1
integer:5
String:a
Person:张三23男研究生
注意:(1)因为集合是无序的,所以输出结果也是无序的。
(2)判断对象是否是数组 obj.getClass().isArray()。
(3)判断对象是否是所属地类obj.getClass().getName()。
第三:删除HashSet中的元素
删除一个元素:hashSet.remove(Object);
删除所有元素:hashSet.clear();
第四:判断是否包含某个元素
if(hashSet.contains(new String("a"))){
System.out.println("String");
}
- Hashmap hashset
- hashmap,hashset
- HashMap,HashSet
- HashSet、HashMap
- HashSet、HashMap
- HashMap&&HashSet
- HashSet HashMap
- hashmap,hashset
- hashSet,hashMap
- HashSet、HashMap
- HashMap, HashSet, HashMap Iterator
- HashMap 、 HashSet 、 HashTable
- HashMap 、 HashSet 、 HashTable
- HashMap, HashTable, HashSet区别
- hashset,hashmap的区别
- HashSet 、HashMap 和 HashTable
- 遍历hashMap、hashSet、Hashtable
- 遍历hashMap、hashSet、Hashtable
- MFC----打开或创建文件
- 实际开发中或产品部署中开发模式(devMode)的设定
- 关于NIOSII的点点滴滴积累
- SmsDemo短信例子程序说明
- 生成全排列
- hashmap,hashset
- .net控件命名规范
- paip.常用android手机软件----语音篇
- 用例图——你真的懂了吗?
- 第九章 DLL文件 windows程序设计 王艳平版
- hdu1297
- restEasy 技术文档
- 第九章 导入表程序 windows程序设计 王艳平版
- json数据格式的使用