面试中关于key/value的问题及map的理解
来源:互联网 发布:淘宝网婴幼儿童车 编辑:程序博客网 时间:2024/06/11 12:59
面试问题1 用什么数据结构来存放电视剧,并且输出为有序。
面试问题2 统计一个字符串中单词的频率,并且频率按从大到小的顺序排列
对于第一个问题:把包含电视剧名字和集数的字符串作为key,对应的存储位置做为value 。用treemap比较合适。
对于第二个问题:单词作为key,出现的次数作为value。由于treemap的默认排序是对key进行排序,用treemap不合适,不如直接用hashmap,存取效率高。排序单独设计。
基础知识:先来理解一下map
map有两种理解方式,一种是当成key/value来理解,可以存放包含key/value属性的对象;另一种更理解可以理解为一种特殊的数组,只不过这个数组的下标【index】可以是
任意对象。
hashmap在存储键值对时借助了“数组+链表”的方式,就是哈希表。
存取元素:HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry 对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。
我们对一个键值对的查询,是分为四步的。
先根据key值计算出hash值以及h值(h值是java实现中处理得到的更优的index索引值)
查找table数组中的h位置,得到相应的键值对链表
根据key值,遍历键值对链表,找到相应的键值对,
从键值对中取出value值。
hashmap()查找,插入,删除的时间复杂度可以认为为O(1);
LinkedHashMap物理结构和hashmap差不多,只不过hashmap中,hashtable里存储的元素为链表的header,而在LinkedHashMap里面,hashTable里存储的元素为双向链表结点,结点的数据元素为header,结点的next或previous指向其他hashTable位置结点,从而可以实现按照插入或者访问顺序存储。
LinkedHashMap的双向链表为循环双向链表。为什么要用循环双向链表而不是普通双向链表,我个人认为这样可以少记一个头节点或者尾结点的位置。迭代器要想正向或逆向打印双链表,只需要知道header位置即可。
(循环双向链表的头部存放的是最久访问的节点或最先插入的节点,尾部为最近访问的或最近插入的节点,迭代器遍历方向是从链表的头部开始到链表尾部结束,在链表尾部有一个空的header节点,该节点不存放key-value内容,为LinkedHashMap类的成员属性,循环双向链表的入口。这句话其实就是描述了一个循环双向链表的结构,尾部都会空一个,作为header。)
迭代器总的过程应该是这样的:LinkedHashMap只有一个入口,就是数组hashtable的头地址。迭代器通过HashTable的头结点next或previou,找到循环双线链表头节点或尾节点,从而可以正向或逆向打印元素。
LinkedHashmap()查找,插入,删除的时间复杂度也为O(1),但却实现了可以按照key的插入顺序或访问顺序输出元素。
treemap的存储结构用的是红黑树。红黑树的操作时间跟二叉查找树的时间复杂度是一样的,执行查找、插入、删除等操作的时间复杂度为O(logn)。
面试问题1的实现
import java.util.*;public class TestTreeMapDelete {public static void main(String[] args) {TreeMap<String, Integer> treemap = new TreeMap<String, Integer>();treemap.put("fengshen_001", 342314);treemap.put("fengshen_004", 322514);treemap.put("fengshen_005", 341319);treemap.put("fengshen_002", 344364);treemap.put("fengshen_004", 322514);System.out.println(treemap);System.out.println(treemap.subMap("fengshen_002", "fengshen_004"));}}
面试问题2的实现:
<pre name="code" class="java">import java.util.*;public class CountOccurenceOfWordsAdv { public static void main(String[] args) { // Text in a string String text = "Have a good day. Have a good class. " + "Have a good visit. Have fun!"; // Create a hash map to hold words and key and count as value HashMap<String, Integer> hashMap = new HashMap<String, Integer>(); StringTokenizer st = new StringTokenizer(text, " .!?"); while (st.hasMoreTokens()) { String key = st.nextToken(); if (hashMap.get(key) != null) { int value = ((Integer)hashMap.get(key)).intValue(); value++; hashMap.put(key, new Integer(value)); } else { hashMap.put(key, new Integer(1)); } } // Get an entry set for the tree map Set<Map.Entry<String, Integer>> entrySet = hashMap.entrySet(); // Get an iterator for the entry set Iterator<Map.Entry<String, Integer>> iterator = entrySet.iterator(); ArrayList<WordOccurrence> list = new ArrayList<WordOccurrence>(); while (iterator.hasNext()) { StringTokenizer st1 = new StringTokenizer(iterator.next().toString(), "="); list.add(new WordOccurrence(st1.nextToken(), Integer.parseInt(st1.nextToken()))); } Collections.sort(list); for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } }}class WordOccurrence implements Comparable { String word; int count; public WordOccurrence(String word, int count) { this.word = word; this.count = count; } public int compareTo(Object o) {// return count - ((WordOccurrence)o).count; return ((WordOccurrence)o).count - count; } public boolean equals(Object o) { return word.equals(((WordOccurrence)o).word); } public String toString() { return word + " " + count; }}
- 面试中关于key/value的问题及map的理解
- 修改Map中确定key对应的value问题
- map key value的排序问题
- Map和Map<key,value>及Map<String, ?>的区别
- STL中map的key和value
- 合并map中key相同的value
- 关于Map类型中对value进行排序的问题
- java Map的问题取得最大value对应的key
- 关于hashMap的key和value的理解
- 根据value取得map中对应的key(笔记)
- 如何取出 Map中key和value的值
- 如何取出 Map中key和value的值
- 如何取出 Map中key和value的值
- 如何取出 Map中key和value的值
- 取出 Map中key和value的值
- 如何取出 Map中key和value的值1
- java 获取 Map中所有的 key 和 value 值
- 如何取出 Map中key和value的值
- kuangbin——线段树专题 E - Just a Hook
- SkipList跳表的实现
- 弹幕效果实现
- HDU 5793 A Boring Question(快速幂+求逆元)
- OJ3311数据结构实验之串三:KMP应用
- 面试中关于key/value的问题及map的理解
- leetcode_c++: Regular Expression Matching(010)
- 从Windows到Linux(二)
- js函数
- node-webkit js 复制粘贴
- C++之stl::string写时拷贝导致的问题
- kuangbin——线段树专题 F - Balanced Lineup
- 安卓百分比布局之RelativeLayout
- C语言二维数组(第十天)