【JavaSE】day06_Map接口_HashMap_hashCode
来源:互联网 发布:有个腿长的女朋友知乎 编辑:程序博客网 时间:2024/05/01 01:34
【JavaSE】day06_Map接口_HashMap_hashCode
1.Map接口
1)java.util.Map
Map看起来像是一个多行两列的表格。每条记录分为两部分:key,value。
其中在一个Map中key是不允许重复的(equals比较)
2)常用实现类:java.util.HashMap(散列算法实现)
java.util.TreeMap(二叉树实现)
3)V put(K k,V v)
将给定的key与value存入到Map中。由于Map中key不允许重复,所以会出现两种情况:
* 1:存入的key在Map中还不存在,那么直接将这对key-value存入Map,返回值为null。
* 2:存入的key在Map中已经存在,那么会将对应的value替换原来这个key对应的value,并将被替换的value值返回。
4)V get(K k)
根据给定的key值获取对应的value。若当前Map中不含有给定的key,则返回值为null。
5)V remove(K k)
将给定的key对应的这一对内容从Map中删除并将对应的value返回。
6)boolean containsKey(K k)
查看当前Map是否包含给定的key。包含的判断依据是根据key的equals比较的结果
代码演示:
package day05;import java.util.HashMap;import java.util.Map;/** * java.util.Map * Map看起来像是一个多行两列的表格 * 每条记录分为两部分:key,value * 其中在一个Map中key是不允许重复的。(equals比较) * *常用实现类:java.util.HashMap(散列算法实现) * java.util.TreeMap(二叉树实现) */public class MapDemo1 {public static void main(String[] args) {/* * 保存成绩单 语文-90 */Map<String,Integer>map = new HashMap<String,Integer>();/* * V put(K k,V v) * 将给定的key与value存入到Map中。 * 由于Map中key不允许重复,所以会出现两种情况: * 1:存入的key在Map中还不存在,那么直接将这对 * key-value存入Map,返回值为null * 2:存入的key在Map中已经存在,那么会将对应的 * value替换原来这个key对应的value,并将被 * 替换的value值返回。 * */map.put("语文",95);map.put("数学",99);map.put("英语",97);map.put("物理",96);map.put("化学",98);/* * 存入顺序与内部顺序不一致 */System.out.println(map);Integer a =map.put("语文1",100);//int a =map.put("语文1",100); //空指针异常,写成Integer可以避免System.out.println(a);System.out.println(map);/* * V get(K k) * 根据给定的key值获取对应的value * 若当前Map中不含有给定的key,则返回值为null */Integer num = map.get("化学");System.out.println(num);/* * V remove(K k) * 将给定的key对应的这一对内容从Map中删除 * 并将对应的value返回。 */num = map.remove("化学");System.out.println(num);System.out.println(map);/* * boolean containsKey(K k) * 查看当前Map是否包含给定的key * 包含的判断依据是根据key的equals比较的结果 */boolean contains = map.containsKey("语文");System.out.println(contains);}}
7)Map的三种遍历方法:
package day05;import java.util.Collection;import java.util.LinkedHashMap;import java.util.Map;import java.util.Set;import java.util.Map.Entry;/** * 遍历Map * 遍历Map有三种方式: * 1:遍历所有的key * 2:遍历每一组键值对 * 3:遍历所有的value(相对不常用) * */public class MapDemo2 {public static void main(String[] args) {/* * LinkedHashMap * 内部使用一个LinkedList维护顺序,可以做到遍历的时候 * 与put的顺序一致。若不许要顺序,通常不使用该类。 */Map<String,Integer> map = new LinkedHashMap<String,Integer>();map.put("语文",95);map.put("数学",98);map.put("英语",95);map.put("物理",93);map.put("化学",90);System.out.println(map);/* * 遍历所有的key: * Set<K> keySet() * 该方法会将所有的key存入一个Set集合后返回, * 所以遍历该集合就相当于遍历到所有的key了。 */Set<String> keySet = map.keySet();for(String key : keySet){System.out.println(key);}/* * 遍历每一组键值对 * Set<Entry> entrySet() * 将每一组键值对(Entry实例)存入一个Set集合后将其返回。 * * Entry是Map的内部类,每一个实例表示一组键值对 * 其中包含两个属性,key,value。 */Set<Entry<String,Integer>> entrySet = map.entrySet();for(Entry<String,Integer> e : entrySet){String key = e.getKey();Integer num = e.getValue();System.out.println(key+"--"+num);}/* * Collection<V> values() * 将当前Map中所有的value值存入一个集合后返回。 */Collection<Integer> values = map.values();for(Integer i : values){System.out.println(i);}}}
2.HashMap
HashMap是Map的一个常用的子类实现。其实使用散列算法实现的。
HashMap内部维护着一个散列数组(就是一个存放元素的数组),我们称其为散列桶,而当我们向HashMap中存入一组键值对时,HashMap首先获取key这个对象的hashcode()方法的返回值,然后使用该值进行一个散列算法,得出一个数字,这个数字就是这组键值对要存入散列数组中的下标位置。
那么得知了下标位置后,HashMap还会查看散列数组当前位置是否包含该元素。(这里要注意的是,散列数组中每个元素并非是直接存储键值对的,而是存入了一个链表,这个链表中的每个节点才是真实保存这组键值对的。)检查是否包含该元素时根据当前要存入的key在当前散列数组对应位置中的链表里是否已经包含这个key,若不包含则将这组键值对存入链表,否则就替换value。
那么在获取元素时,HashMap同样先根据key的hashcode值进行散列算法,找到它在散列数组中的位置,然后遍历该位置的链表,找到该key所对应的value之后返回。
看到这里可能有个疑问,链表中应该只能存入一个元素,那么HashMap是如何将key-value存入链表的某个节点的呢?实际上,HashMap会将每组键值对封装为一个Entry的实例,然后将该实例存入链表。
3.hashCode
当我们使用自定义类型的实例作为HashMap中key的值时,这个类的equals与hashCode的结果直接影响着HashMap查询的效率。
* 要避免一件事的产生:
hashCode值相同,但是equals比较不为true!!这会严重影响 HashMap效率。
* JAVA API文档中对于这两个方法的重写有这样的要求:
当我们重写一个类的equals方法时,就应当连同重写hashCode方法。
*还应同时满足:
当两个对象equals比较为true时,hashCode返回的值应当相等。反过来不强制,但最好也不同,否则影响HashMap性能。
hashCode方法返回值应当是一个稳定的值,意思就是:当确定equals方法比较结果的属性没有发生改变的前提下,多次调用hashCode方法返回值应当相同。
代码演示:
package day05;/** * 该类用于练习重写equals与hashCode的注意事项: * 当我们使用自定义类型的实例作为HashMap中key的值时, * 这个类的equals与hashCode的结果直接影响着HashMap查询的效率。 * 要避免一件事的产生: * hashCode值相同,但是equals比较不为true!!这会严重影响 * HashMap效率。 * JAVA API文档中对于这两个方法的重写有这样的要求: * 当我们重写一个类的equals方法时,就应当连同重写hashCode方法。 *还应同时满足: *当两个对象equals比较为true时,hashCode返回的值应当相等。 *反过来不强制,但最好也不同,否则影响HashMap性能。 *hashCode方法返回值应当是一个稳定的值,意思就是:当确定equals *方法比较结果的属性没有发生改变的前提下,多次调用hashCode方法 *返回值应当相同。 * */public class Cell {private int row;private int col;public Cell(int row, int col) {super();this.row = row;this.col = col;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + col;result = prime * result + row;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;final Cell other = (Cell) obj;if (col != other.col)return false;if (row != other.row)return false;return true;}}
4.Map小案列
package day05;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.Map.Entry;/** * 现有字符串"good good study, day day up.",统计其中各个字符出现的次数。 * */public class MapDemo {public static void main(String[] args) {String str = "good good study, day day up.";summary(str);}public static Map<Character,Integer> summary(String str){// "good good study, day day up."Map<Character,Integer> map = new HashMap<Character,Integer>();//去除字符串中的空格和标点符号//regex = "[^a-zA-Z]+"str = str.replaceAll("[^a-zA-Z]+","");System.out.println(str);for(int i=0;i<str.length();i++){char c = str.charAt(i);if(map.containsKey(c)){map.put(c,map.get(c)+1);}else{map.put(c,1);}}//新循环遍历Set<Entry<Character,Integer>>entrySet = map.entrySet();for(Entry<Character,Integer> e : entrySet){System.out.println(e.getKey()+"--"+e.getValue());}//Iterator迭代器遍历 key-valueIterator<Entry<Character,Integer>> it2 = entrySet.iterator();while(it2.hasNext()){//it.next()每次循环的时候只能出现一次,否则可能抛异常Entry<Character,Integer> e = it2.next(); char key = e.getKey();Integer value = e.getValue();System.out.println(key +"--" +value);}//迭代器遍历keySet<Character> keySet = map.keySet();Iterator<Character> it = keySet.iterator();while(it.hasNext()){System.out.print(it.next()+" ");}System.out.println();return null;}}
- 【JavaSE】day06_Map接口_HashMap_hashCode
- JAVASE接口
- javaSE-面向对象-接口
- JavaSE------interface接口
- JavaSE 学习参考:接口
- JavaSE---interface(接口)
- javaSE之接口理解
- JavaSE基础-02-接口
- 【javase复习】## day9 Map接口 ##
- JAVASE--04--多态,抽想类,接口
- JavaSE 学习参考:List接口
- 【JavaSE】接口和抽象类
- [javase]接口的工厂模式
- JavaSE复习之五 基础知识:接口
- JavaSE--继承、抽象类及接口
- JavaSe基础(17)-- interface 接口
- javaSE学习笔记——接口
- 【javase复习】## day4 抽象类、接口 ##
- JVM调优总结 -Xms -Xmx -Xmn -Xss
- Redis源码分析---字典dict
- 两道几何题的求解
- 文章标题
- HDU1059 多重背包 多重部分和问题DP
- 【JavaSE】day06_Map接口_HashMap_hashCode
- How to use the Service Bus relay service
- 深入剖析Tomcat类加载机制
- Broadcast广播机制
- Android非5.0系统下singleTask singleInstance startActivityForResult
- R 语言 ubantu配置以及安装
- 2015-08-26
- Kids and Prizes 来源: <http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85996#problem/B>
- Android UI设计——AutoCompleteTextView