Map底层有HashMap或者TreeMap,主要运用的是HashMap。
Map
- public class Main{
- public static void main(String[] args) {
- Map
map = new HashMap<>(); - map.put("hello",10);
- map.put("love",20);
- map.put("map",9);
- System.out.println(map);
- }
- }
输出发现,定义时“hello”在前,“love”在后,但是输出时却先输出“love”,后输出“hello”。
这是因为存储的时候,是根据一个函数来进行存储的。具体存储在哪里,是由这个函数确定的,这个函数是哈希函数
方法 | 解释 |
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 | 返回所有 key 的不重复集合 |
Collection | 返回所有 value 的可重复集合 |
Set | 返回所有的 key-value 映射关系 |
boolean containsKey(Object key) | 判断是否包含 key |
boolean containsValue(Object value) | 判断是否包含 |
1.如keySet()这个函数,作用是返回所有的key,返回值的类型是Set
- public class Main {
- public static void main(String[] args) {
- Map
map = new HashMap<>(); - map.put("hello",10);
- map.put("love",20);
- map.put("map",9);
-
- Set
set = map.keySet(); - System.out.println(set);
- }
- }
输出结果,即就是返回所有的key。
2.再如entrySet()这个函数,它的返回值是Set
Set
> set = map.entrySet();
set的类型是Set
例如下面代码
- public class Main{
- public static void main(String[] args) {
- Map
map = new HashMap<>(); - map.put("hello",10);
- map.put("love",20);
- map.put("map",9);
-
- System.out.println(map);
-
- Set
> set = map.entrySet(); - for (Map.Entry
i:set) { - System.out.println(i.getKey() +" "+ i.getValue() );
- }
- }
- }
输出结果:
1. Map 是一个接口,不能直接实例化对象 ,如果 要实例化对象只能实例化其实现类 TreeMap 或者 HashMap2. Map 中存放键值对的 Key 是唯一的, value 是可以重复的3. 在 Map 中插入键值对时, key 不能为空,否则就会抛 NullPointerException 异常 ,但是 value 可以为空(针对的是TreeMap)4. Map 中的 Key 可以全部分离出来,存储到 Set 中 来进行访问 ( 因为 Key 不能重复 ) 。5. Map 中的 value 可以全部分离出来,存储在 Collection 的任何一个子集合中 (value 可能有重复 ) 。6. Map 中键值对的 Key 不能直接修改, value 可以修改,如果要修改 key ,只能先将该 key 删除掉,然后再来进行重新插入。
Map底层结构 | TreeMap | HashMap |
底层结构 | 红黑树 | 哈希桶 |
增/删/查 的时间复杂度 | O(log(2)(N)) | O(1) |
是否有序 | 关于key有序 | 无序 |
线程安全 | 不安全 | 不安全 |
增/删/查 的区别 | 需要进行元素比较 | 通过哈希函数计算哈希地址 |
比较与覆写 | key必须能够进行比较,否则抛出ClassCastException异常 |
自定义类型需要覆写
equals
和
hashCode
方法
|
应用场景 |
需要
Key
有序场景下
|
Key
是否有序不关心,需要更高的
时间性能
|
HashMap的时间复杂度为O(1),所以通常情况下,一般使用的是HashMap。
Set会自动去重
- public class Main{
- public static void main(String[] args) {
- Set
set = new HashSet<>(); - set.add(1);
- set.add(2);
- set.add(3);
- set.add(1);
- System.out.println(set);
- }
- }
输出:
方法 | 解释 |
boolean add(E e)
|
添加元素,但重复元素不会被添加成功
|
void clear()
|
清空集合
|
boolean contains(Object o)
|
判断
o
是否在集合中
|
Iterator | 返回迭代器 |
boolean remove(Object o)
| 删除集合中的 o |
int size()
| 返回set中元素的个数 |
boolean isEmpty()
| 检测set是否为空,空返回true,否则返回false |
Object[] toArray()
| 将set中的元素转换为数组返回 |
boolean containsAll(Collection> c)
|
集合
c
中的元素是否在
set
中全部存在,是返回
true
,否则返回
false
|
boolean addAll(Collection extends E> c)
|
将集合
c
中的元素添加到
set
中,可以达到去重的效果
|
对于Iterator
- public class Main {
- public static void main2(String[] args) {
- Set
set = new HashSet<>(); - set.add(1);
- set.add(2);
- set.add(3);
- System.out.println(set);
-
- Iterator
iterator = set.iterator(); - while(iterator.hasNext()){
- System.out.println(iterator.next());
- }
- }
- }
输出结果:
1. Set 是继承自 Collection 的一个接口类2. Set 中只存储了 key ,并且要求 key 一定要唯一3. Set 的底层是使用 Map 来实现的,其使用 key 与 Object 的一个默认对象作为键值对插入到 Map 中的4. Set 最大的功能就是对集合中的元素进行去重5. 实现 Set 接口的常用类有 TreeSet 和 HashSet ,还有一个 LinkedHashSet , LinkedHashSet 是在 HashSet 的基础上维护了一个双向链表来记录元素的插入次序。6. Set 中的 Key 不能修改,如果要修改,先将原来的删除掉,然后再重新插入7. Set 中不能插入 null 的 key 。8. TreeSet 和 HashSet 的区别
Set
底层结构
| TreeSet | HashSet |
底层结构
|
红黑树
|
哈希桶
|
插入
/
删除
/
查找时间
复杂度
| O(log(2)(N)) |
O(1)
|
是否有序
|
关于
Key
有序
|
不一定有序
|
线程安全
|
不安全
|
不安全
|
插入
/
删除
/
查找区别
|
按照红黑树的特性来进行插入和删除
|
1.
先计算
key
哈希地址
2.
然后进行
插入和删除
|
比较与覆写
|
key
必须能够比较,否则会抛出
ClassCastException
异常
|
自定义类型需要覆写
equals
和
hashCode
方法
|
应用场景
|
需要
Key
有序场景下
|
Key
是否有序不关心,需要更高的时间性能
|
一般情况下用的是HashSet