如何把一个Map转化为List
日常开发中,我们经常遇到这种场景,把一个Map转化为List。map转List有以下三种转化方式:
- 把map的键key转化为list
- 把map的值value转化为list
- 把map的键值key-value转化为list
伪代码如下:
- List
- keyList
- =
-
- new
-
- ArrayList
- (
- map
- .
- keySet
- ());
- List
- valueList
- =
-
- new
-
- ArrayList
- (
- map
- .
- values
- ());
- List
- entryList
- =
-
- new
-
- ArrayList
- (
- map
- .
- entrySet
- ());
示例代码:
运行结果:
- [
- 1
- ,
-
- 2
- ,
-
- 3
- ]
- [
- whx
- ,
- jay
- ,
- huaxiao
- ]
- [
- 1
- =
- whx
- ,
-
- 2
- =
- jay
- ,
-
- 3
- =
- huaxiao
- ]
2、如何遍历一个Map
我们经常需要遍历一个map,可以有以下两种方式实现:
通过entrySet+for实现遍历
- for
- (
- Entry
- entry
- :
- map
- .
- entrySet
- ())
-
- {
-
- K key
- =
- entry
- .
- getKey
- ();
-
- V value
- =
- entry
- .
- getValue
- ();
- }
实例代码:
通过Iterator+while实现遍历
- Iterator
- itr
- =
- map
- .
- entrySet
- ().
- iterator
- ();
- while
- (
- itr
- .
- hasNext
- ())
-
- {
-
- Entry
- entry
- =
- itr
- .
- next
- ();
-
- K key
- =
- entry
- .
- getKey
- ();
-
- V value
- =
- entry
- .
- getValue
- ();
- }
实例代码:
运行结果:
- key
- :
- 1
- ,
- value
- :
- whx
- key
- :
- 2
- ,
- value
- :
- jay
- key
- :
- 3
- ,
- value
- :
- huaxiao
3、如何根据Map的keys进行排序
对Map的keys进行排序,在日常开发很常见,主要有以下两种方式实现。
把Map.Entry放进list,再用Comparator对list进行排序
- List
- list
- =
-
- new
-
- ArrayList
- (
- map
- .
- entrySet
- ());
- Collections
- .
- sort
- (
- list
- ,
-
- (
- Entry
- e1
- ,
-
- Entry
- e2
- )->
-
- {
-
- return
- e1
- .
- getKey
- ().
- compareTo
- (
- e2
- .
- getKey
- ());
- });
实例代码:
使用SortedMap+TreeMap+Comparator实现
- SortedMap
- sortedMap
- =
-
- new
-
- TreeMap
- (
- new
-
- Comparator
- ()
-
- {
-
- @Override
-
- public
-
- int
- compare
- (
- K k1
- ,
- K k2
- )
-
- {
-
- return
- k1
- .
- compareTo
- (
- k2
- );
-
- }
- });
- sortedMap
- .
- putAll
- (
- map
- );
实例代码:
运行结果:
- key
- :
- 1999
- ,
- value
- :
- whx
- key
- :
- 2010
- ,
- value
- :
- jay
- key
- :
- 3010
- ,
- value
- :
- huaxiao
4、如何对Map的values进行排序
- List
- list
- =
-
- new
-
- ArrayList
- (
- map
- .
- entrySet
- ());
- Collections
- .
- sort
- (
- list
- ,
-
- (
- Entry
- e1
- ,
-
- Entry
- e2
- )
-
- ->{
-
- return
- e1
- .
- getValue
- ().
- compareTo
- (
- e2
- .
- getValue
- ());
-
- });
实例代码:
运行结果:
- key
- :
- 3010
- ,
- value
- :
- huaxiao
- key
- :
- 2010
- ,
- value
- :
- jay
- key
- :
- 1999
- ,
- value
- :
- whx
5、如何初始化一个静态/不可变的Map
初始化一个静态不可变的map,单单static final+static代码块还是不行的,如下:
这里面,map继续添加元素(3,"three"),发现是OK的,运行结果如下:
- key
- :
- 1
- ,
- value
- :
- one
- key
- :
- 2
- ,
- value
- :
- two
- key
- :
- 3
- ,
- value
- :
- three
真正实现一个静态不可变的map,需要Collections.unmodifiableMap,代码如下:
运行结果如下:
可以发现,继续往map添加元素是会报错的,实现真正不可变的map。
6、HashMap, TreeMap, and Hashtable,ConcurrentHashMap的区别
HashMap TreeMap Hashtable ConcurrentHashMap
有序性 否 是 否 否
null k-v 是-是 否-是 否-否 否-否
线性安全 否 否 是 是
时间复杂度 O(1) O(log n) O(1) O(log n)
底层结构 数组+链表 红黑树 数组+链表 红黑树
7、如何创建一个空map
如果map是不可变的,可以这样创建:
- Map
- map
- =
- Collections
- .
- emptyMap
- ();
- or
- Map
- <
- String
- ,
- String
- >
- map
- =
- Collections
- .<
- String
- ,
-
- String
- >
- emptyMap
- ();
如果你希望你的空map可以添加元素的,可以这样创建
- Map
- map
- =
-
- new
-
- HashMap
- ();
8、有关于map的复制
有关于hashmap的复制,在日常开发中,使用也比较多。主要有 =,clone,putAll,但是他们都是浅复制,使用的时候注意啦,可以看一下以下例子:
例子一,使用=复制一个map:
运行结果:
- {
- 1
- =
- User
- {
- name
- =
- ‘jay‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
-
- Changes
- reflect
- in
- both maps
-
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
从运行结果看出,对cloneMap修改,两个map都改变了,所以=是浅复制。
例子二,使用hashmap的clone复制:
运行结果:
- {
- 1
- =
- User
- {
- name
- =
- ‘jay‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
-
- Changes
- reflect
- in
- both maps
-
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
从运行结果看出,对cloneMap修改,两个map都改变了,所以hashmap的clone也是浅复制。
例子三,通过putAll操作
运行结果:
- {
- 1
- =
- User
- {
- name
- =
- ‘jay‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
-
- Changes
- reflect
- in
- both maps
-
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
从运行结果看出,对cloneMap修改,两个map都改变了,所以putAll还是浅复制。
那么,如何实现深度复制呢?
可以使用序列化实现,如下为谷歌Gson序列化HashMap,实现深度复制的例子:
运行结果:
- {
- 1
- =
- User
- {
- name
- =
- ‘jay‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
-
- Changes
- reflect
- in
- only one map
-
- {
- 1
- =
- User
- {
- name
- =
- ‘jay‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
- {
- 1
- =
- User
- {
- name
- =
- ‘test‘
- ,
- age
- =
- 26
- },
-
- 2
- =
- User
- {
- name
- =
- ‘fany‘
- ,
- age
- =
- 25
- }}
从运行结果看出,对cloneMap修改,userMap没有被改变,所以是深度复制