一:搜索
本节所要介绍的map
和set
是一种专门用来进行搜索的容器或者数据结构。一般我们把搜索的数据称之为关键字(key
),把关键字的对应称之为值(value
),合称为 key-value
键值对,主要会有以下两种模型
- 纯
key
模型:例如快速查找某个名字是否存在于通讯录之中 key-value
模型:例如统计一篇文章中每个单词出现的次数,也即<单词,单词出现的次数>
二:Map使用
(1)Map介绍
Map:Map是一个接口类,它没有继承Collection
,所存储的是<K.V>
键值对,并且K一定是唯一的,不可以重复
- 由于
Map
是一个接口所以不可以直接实例化对象,如果要实例化,则只能实例化其实现类TreeMap
或者HashMap
Map
中key
必须唯一但value
可以重复Map
中key
不能直接修改但value
可以修改(如果要修改key
则必须先删除再插入)Map
中的key
可以全部分离出来存储到set
中去;Map
中的value
可以全部分离出来存储到Collection
的任何一个子集合中去
(2)TreeMap和HashMap区别
比较项目 | TreeMap | HashMap |
---|---|---|
底层结构 | 红黑树 | 哈希桶 |
操作时间复杂度 | O(log_{2}N) | O(1) |
是否有效 | 关于key 有序 |
无序 |
是否线程安全 | 不安全 | 不安全 |
操作区别 | 需要进行元素比较 | 通过哈希函数计算哈希地址 |
比较与重写 | key 必须要求可以比较 |
自定义类型需要重写equals 和hashCode 方法 |
应用场景 | 要求key 有序场景下 |
关注时间性能 |
(3)Map常用方法说明
Map常用方法:如下
V get(Object key)
:返回key
对应的value
V getOrDefault(Object key, V defaultValue)
:返回key
对应的value
,如果key
不存在则返回默认值V put(K key, V value)
:设置key
对应的value
V remove(Object key)
:删除key
对应的映射关系Set<K> KeySet()
:返回所有Key
的不重复集合Collection<V> values()
:返回所有value
的可重复集合Set<Map.Entry<K,V>> entrySet()
:返回所有key-value
映射关系Boolean containsKey(Object key)
:判断是否包含key
Boolean containsValue(Object value)
:判断是否包含value
这里对于Map.Entry<K, V>
要重点说明一下: Map.Entry<K, V>
是Map
的一个内部接口,它将key-value
打包为了一个新的类型。这主要会在遍历中使用,调用Map的entrySet()
方法将会返回这个Map.Entry<K, V>
类型。在这以前,我们遍历一个Map
集合时,需要获取key
的值,然后再获取value
的值,这是很繁琐和费时的。而现在通过entrySet()
的方法返回一个Map.Entry<K, V>
后,就可以通过它所提供的getKey()
方法和getValue()
方法获取key
和value
- 相关代码见下面示例
(4)使用示例
A:TreeMap使用示例
TreeMap使用示例:如下例,注意
TreeMap
是按照key
有序的,所以在传入的自定义类型时一定要实现其比较功能TreeMap
的key
值不可以设置为null
- 如果
put
了两次相同的key
,那么第二次就会覆盖第一次
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
public class TestTreeMapDemo {
public static void main(String[] args) {
Map<String ,Integer> map = new TreeMap<>();
map.put("hello", 11);
map.put("world", 22);
map.put("we", 44);
map.put("are", 55);
map.put("friends", 33);
System.out.println("hello:" + map.get("hello"));
System.out.println("hello world:" + map.get("hello world"));
System.out.println("hello:" + map.getOrDefault("hello world", -1)); //如果没有则返回-1
System.out.println("AllKey:" + map.keySet()); //返回key集合
System.out.println("AllValues:" + map.values()); //返回value集合
System.out.println("key-friends是否存在:" + map.containsKey("friends"));
System.out.println("value-99是否存在:" + map.containsValue(99));
//Map.Entry示例
System.out.println("Map.Entry示例-----------------------------------------------");
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
for(Map.Entry<String, Integer> entry : entrySet){
System.out.println("key:" + entry.getKey() + "-" + "value:" + entry.getValue());
}
}
}
B:HashMap使用示例
TreeMap使用示例:如下例,注意
- 使用HashMap存取元素时你会发现它和你的存放次序是不一致的,这是因为在存放元素时会利用该元素做
hash
运算,相同的元素的hash
结果是一样的,所以它和存放次序无关,只和元素本身有关 HashMap
的key
值可以设置为null
三:Set使用
(1)Set使用
Setp:Set
是继承自Collection
的接口类且Set
中只存储key
(要求key
唯一)
-
Set
底层采用Map
实现,其使用Key
与Object
的一个默认对象作为键值对插入到Map
中
-
Set
最大的功能就是对集合中的元素进行去重 -
实现
Set
接口的常用类有TreeSet
、HashSet
、LinkedHashSet
,其中LinkedHashSet
是在HashSet
基础上维护了一个双向链表来记录元素的插入次序 -
Set
中的key
不可以修改(如果要修改需要先删除再插入) -
Set
中不能插入null
(2)TreeSet和HashSet区别
比较项目 | TreeMap | HashMap |
---|---|---|
底层结构 | 红黑树 | 哈希桶 |
操作时间复杂度 | O(log_{2}N) | O(1) |
是否有效 | 关于key 有序 |
不一定有序 |
是否线程安全 | 不安全 | 不安全 |
操作区别 | 按照红黑树特性操作 | 通过哈希函数计算哈希地址 |
比较与重写 | key 必须要求可以比较 |
自定义类型需要重写equals 和hashCode 方法 |
应用场景 | 要求key 有序场景下 |
关注时间性能 |
(3)Set常用方法说明
Map常用方法:如下
Boolean add(E, e)
:添加元素void clear()
:清空集合Boolean contains(Object o)
:判断o
是否在集合中Iterator<E> iterator()
:返回迭代器int size()
:返回set
中元素的个数Boolean isEmpty()
:检测set
是否为空Object[] toArray()
:将set
中的元素转换为数组返回Boolean containsAll(Collection<?> c)
:判断集合c
中的元素是否在set
中是否全部存在Boolean addAll(Collection<? extends E>c)
:将集合c
中的元素添加到set
中(可以达到去重效果)
(4)HashSet使用示例
import java.util.*;
public class TestTreeSetDemo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
set.add("apple");
set.add("orange");
set.add("peach");
set.add("banana");
System.out.println("打印:" + set);
System.out.println("返回set大小:" + set.size());
System.out.println("判断\"melon\"是否存在:" + set.contains("melon"));
set.remove("peach");
System.out.println("删除\"peach\":" + set);
//迭代器
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.print(it.next() + "-");
}
System.out.println();
}
}
评论区