苏州网站建设姜超,济南做网络安全的公司,网站主体备案号,动漫制作专业可以升大专吗前言 前两篇文章我们研究了二叉搜索树与哈希表的结构与特点#xff0c;他们二者是Map与Set这两个接口实现的底层结构#xff0c;他们利用了搜索树与哈希表查找效率高这一特点#xff0c;是一种专门用来进行搜索操作的容器或数据结构。本篇文章就让我们一起来梳理这两个接口的…前言 前两篇文章我们研究了二叉搜索树与哈希表的结构与特点他们二者是Map与Set这两个接口实现的底层结构他们利用了搜索树与哈希表查找效率高这一特点是一种专门用来进行搜索操作的容器或数据结构。本篇文章就让我们一起来梳理这两个接口的特性与用法吧 在介绍这两个接口前先说明一下Key-value模型吧
一般把搜索的数据称为关键字Key和关键字对应的称为值Value将其称之为Key-value的键值对所以模型会有两种 1. 纯 key 模型比如 有一个英文词典快速查找一个单词是否在词典中快速查找某个名字在不在通讯录中 2. Key-Value 模型比如 统计文件中每个单词出现的次数统计结果是每个单词都有与其对应的次数单词单词出现的次数梁山好汉的江湖绰号每个好汉都有自己的江湖绰号 而 Map 中存储的就是 key-value 的键值对 Set 中只存储了 Key 一、Map Map 是一个接口类该类没有继承自 Collection 该类中存储的是 K,V 结构的键值对并且 K 一定是唯一的不 能重复。 Map.EntryK, V 是 Map 内部实现的用来存放 key, value 键值对映射关系的内部类该内部类中主要提供了key, value的获取value的设置以及Key的比较方式。 注意Map.EntryK,V并没有提供设置Key的方法 Map 的常用方法说明 注意 1. Map 是一个接口不能直接实例化对象如果 要实例化对象只能实例化其实现类 TreeMap 或者 HashMap 2. Map 中存放键值对的 Key 是唯一的 value 是可以重复的 3. 在 TreeMap 中插入键值对时 key 不能为空否则就会抛 NullPointerException 异常value可以为空。但是HashMap的key和value都可以为空。 4. Map 中的 Key 可以全部分离出来存储到 Set 中来进行访问(因为Key不能重复)。 5. Map 中的 value 可以全部分离出来存储在 Collection 的任何一个子集合中(value可能有重复)。 6. Map中键值对的Key不能直接修改value可以修改如果要修改key只能先将该key删除掉然后再来进行重新插入。 HashMap的简单实现 public class HashBuck2K,V {static class NodeK,V {public K key;public V val;public NodeK,V next;public Node(K key,V val) {this.key key;this.val val;}}public NodeK,V[] array (NodeK,V[])new Node[10];//public NodeK,V[] array new NodeK,V[10];public int usedSize;public double loadFactor 0.75;public void put(K key,V val) {int hash key.hashCode();int index hash % array.length;NodeK,V cur array[index];//1. 遍历当前链表 是否存在当前值while (cur ! null) {if(cur.key.equals(key)) {cur.val val;return;}cur cur.next;}//2. 说明 没有当前值此时进行 头插NodeK,V node new NodeK,V(key,val);node.next array[index];array[index] node;usedSize;}public V get(K key) {int hash key.hashCode();int index hash % array.length;NodeK,V cur array[index];//1. 遍历当前链表 是否存在当前值while (cur ! null) {if(cur.key.equals(key)) {return cur.val;}cur cur.next;}return null;}
} TreeMap使用示例 import java.util.TreeMap;
import java.util.Map;
public static void TestMap(){MapString, String m new TreeMap();
// put(key, value):插入key-value的键值对
// 如果key不存在会将key-value的键值对插入到map中,返回nullm.put(林冲, 豹子头);m.put(鲁智深, 花和尚);m.put(武松, 行者);m.put(宋江, 及时雨);String str m.put(李逵, 黑旋风);System.out.println(m.size());System.out.println(m);
// put(key,value): 注意key不能为空但是value可以为空
// key如果为空会抛出空指针异常
//m.put(null, 花名);str m.put(无名, null);System.out.println(m.size());
// put(key, value):
// 如果key存在会使用value替换原来key所对应的value返回旧valuestr m.put(李逵, 铁牛);
// get(key): 返回key所对应的value
// 如果key存在返回key所对应的value
// 如果key不存在返回nullSystem.out.println(m.get(鲁智深));System.out.println(m.get(史进));
//GetOrDefault(): 如果key存在返回与key所对应的value如果key不存在返回一个默认值System.out.println(m.getOrDefault(李逵, 铁牛));System.out.println(m.getOrDefault(史进, 九纹龙));System.out.println(m.size());
//containKey(key)检测key是否包含在Map中时间复杂度O(logN)
// 按照红黑树的性质来进行查找
// 找到返回true否则返回falseSystem.out.println(m.containsKey(林冲));System.out.println(m.containsKey(史进));
// containValue(value): 检测value是否包含在Map中时间复杂度: O(N)
// 找到返回true否则返回falseSystem.out.println(m.containsValue(豹子头));System.out.println(m.containsValue(九纹龙));
// 打印所有的key
// keySet是将map中的key防止在Set中返回的for(String s : m.keySet()){System.out.print(s );}System.out.println();
// 打印所有的value
// values()是将map中的value放在collect的一个集合中返回的for(String s : m.values()){System.out.print(s );}System.out.println();
// 打印所有的键值对
// entrySet(): 将Map中的键值对放在Set中返回了for(Map.EntryString, String entry : m.entrySet()){System.out.println(entry.getKey() --- entry.getValue());}System.out.println();
} 二、Set Set与Map主要的不同有两点Set是继承自Collection的接口类Set中只存储了Key。 常见方法说明 注意 1. Set是继承自Collection的一个接口类 2. Set中只存储了key并且要求key一定要唯一 3. TreeSet的底层是使用Map来实现的其使用key与Object的一个默认对象作为键值对插入到Map中的 4. Set最大的功能就是对集合中的元素进行去重 5. 实现Set接口的常用类有TreeSet和HashSet还有一个LinkedHashSetLinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。 6. Set中的Key不能修改如果要修改先将原来的删除掉然后再重新插入 7. TreeSet中不能插入null的keyHashSet可以。 TreeSet使用示例 import java.util.TreeSet;
import java.util.Iterator;
import java.util.Set;
public static void TestSet(){SetString s new TreeSet();// add(key): 如果key不存在则插入返回ture// 如果key存在返回falseboolean isIn s.add(apple);s.add(orange);s.add(peach);s.add(banana);System.out.println(s.size());System.out.println(s);isIn s.add(apple);// add(key): key如果是空抛出空指针异常//s.add(null);// contains(key): 如果key存在返回true否则返回falseSystem.out.println(s.contains(apple));System.out.println(s.contains(watermelen));// remove(key): key存在删除成功返回true// key不存在删除失败返回false// key为空抛出空指针异常s.remove(apple);System.out.println(s);s.remove(watermelen);System.out.println(s);IteratorString it s.iterator();while(it.hasNext()){System.out.print(it.next() );}System.out.println();
} 总结 Map与Set这两个接口由于出色的查找效率为之后的一些算法题中在优化时间上发挥着重要的作用不过由于创建需要开辟大量空间是典型的空间换时间在实际应用中应该根据需要选用。还是哪句话没有最好的数据结构只有最适合的数据结构。 那么本篇文章就到此为止了如果觉得这篇文章对你有帮助的话可以点一下关注和点赞来支持作者哦。作者还是一个萌新如果有什么讲的不对的地方欢迎在评论区指出希望能够和你们一起进步✊