前言:
今天大家对“java mapisempty”都比较关怀,你们都想要了解一些“java mapisempty”的相关知识。那么小编也在网络上搜集了一些有关“java mapisempty””的相关内容,希望我们能喜欢,同学们一起来学习一下吧!推荐阅读:6大面试技能树:JAVA基础+JVM+算法+数据库+计算机网络+操作系统都是“Redis惹的祸”,害我差点挂在美团三面,真是“虚惊一场”前言
最近几天看了几篇有关于Java Map的外国博文,写得非常不错,所以整理了Java map 应该掌握的8个问题,都是日常开发司空见惯的问题,希望对大家有帮助;如果有不正确的地方,欢迎提出,万分感谢哈~
本章节所有代码demo已上传github
1、如何把一个Map转化为List
日常开发中,我们经常遇到这种场景,把一个Map转化为List。map转List有以下三种转化方式:
把map的键key转化为list把map的值value转化为list把map的键值key-value转化为list
伪代码如下:
// key listList keyList = new ArrayList(map.keySet());// value listList valueList = new ArrayList(map.values());// key-value listList entryList = new ArrayList(map.entrySet());
示例代码:
public class Test { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(2, "jay"); map.put(1, "whx"); map.put(3, "huaxiao"); //把一个map的键转化为list List<Integer> keyList = new ArrayList<>(map.keySet()); System.out.println(keyList); //把map的值转化为list List<String> valueList = new ArrayList<>(map.values()); System.out.println(valueList); 把map的键值转化为list List entryList = new ArrayList(map.entrySet()); System.out.println(entryList); }}
运行结果:
[1, 2, 3][whx, jay, huaxiao][1=whx, 2=jay, 3=huaxiao]2、如何遍历一个Map
我们经常需要遍历一个map,可以有以下两种方式实现:
通过entrySet+for实现遍历
for(Entry entry: map.entrySet()) { // get key K key = entry.getKey(); // get value V value = entry.getValue();}
实例代码:
public class EntryMapTest { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(2, "jay"); map.put(1, "whx"); map.put(3, "huaxiao"); for(Map.Entry entry: map.entrySet()) { // get key Integer key = (Integer) entry.getKey(); // get value String value = (String) entry.getValue(); System.out.println("key:"+key+",value:"+value); } }}通过Iterator+while实现遍历
Iterator itr = map.entrySet().iterator();while(itr.hasNext()) { Entry entry = itr.next(); // get key K key = entry.getKey(); // get value V value = entry.getValue();}
实例代码:
public class IteratorMapTest { public static void main(String[] args) { Map<Integer, String> map = new HashMap<>(); map.put(2, "jay"); map.put(1, "whx"); map.put(3, "huaxiao"); Iterator itr = map.entrySet().iterator(); while(itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); // get key Integer key = (Integer) entry.getKey(); // get value String value = (String) entry.getValue(); System.out.println("key:"+key+",value:"+value); } }}
运行结果:
key:1,value:whxkey:2,value:jaykey:3,value:huaxiao3、如何根据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());});
实例代码:
public class SortKeysMapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("2010", "jay"); map.put("1999", "whx"); map.put("3010", "huaxiao"); List<Map.Entry<String,String>> list = new ArrayList<>(map.entrySet()); Collections.sort(list, (Map.Entry e1, Map.Entry e2)-> { return e1.getKey().toString().compareTo(e2.getKey().toString()); }); for (Map.Entry entry : list) { System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue()); } }}使用SortedMap+TreeMap+Comparator实现
SortedMap sortedMap = new TreeMap(new Comparator() { @Override public int compare(K k1, K k2) { return k1.compareTo(k2); }});sortedMap.putAll(map);
实例代码:
public class SortKeys2MapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("2010", "jay"); map.put("1999", "whx"); map.put("3010", "huaxiao"); SortedMap sortedMap = new TreeMap(new Comparator<String>() { @Override public int compare(String k1, String k2) { return k1.compareTo(k2); } }); sortedMap.putAll(map); Iterator itr = sortedMap.entrySet().iterator(); while(itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); // get key String key = (String) entry.getKey(); // get value String value = (String) entry.getValue(); System.out.println("key:"+key+",value:"+value); } }}
运行结果:
key:1999,value:whxkey:2010,value:jaykey:3010,value:huaxiao4、如何对Map的values进行排序
List list = new ArrayList(map.entrySet());Collections.sort(list, (Entry e1, Entry e2) ->{ return e1.getValue().compareTo(e2.getValue()); });
实例代码:
public class SortValuesMapTest { public static void main(String[] args) { Map<String, String> map = new HashMap<>(); map.put("2010", "jay"); map.put("1999", "whx"); map.put("3010", "huaxiao"); List <Map.Entry<String,String>>list = new ArrayList<>(map.entrySet()); Collections.sort(list, (Map.Entry e1, Map.Entry e2)-> { return e1.getValue().toString().compareTo(e2.getValue().toString()); } ); for (Map.Entry entry : list) { System.out.println("key:" + entry.getKey() + ",value:" + entry.getValue()); } }}
运行结果:
key:3010,value:huaxiaokey:2010,value:jaykey:1999,value:whx5、如何初始化一个静态/不可变的Map
初始化一个静态不可变的map,单单static final+static代码还是不行的,如下:
public class Test1 { private static final Map <Integer,String>map; static { map = new HashMap<Integer, String>(); map.put(1, "one"); map.put(2, "two"); } public static void main(String[] args) { map.put(3, "three"); Iterator itr = map.entrySet().iterator(); while(itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); // get key Integer key = (Integer) entry.getKey(); // get value String value = (String) entry.getValue(); System.out.println("key:"+key+",value:"+value); } }}
这里面,map继续添加元素(3,"three"),发现是OK的,运行结果如下:
key:1,value:onekey:2,value:twokey:3,value:three
真正实现一个静态不可变的map,需要Collections.unmodifiableMap,代码如下:
public class Test2 { private static final Map<Integer, String> map; static { Map<Integer,String> aMap = new HashMap<>(); aMap.put(1, "one"); aMap.put(2, "two"); map = Collections.unmodifiableMap(aMap); } public static void main(String[] args) { map.put(3, "3"); Iterator itr = map.entrySet().iterator(); while(itr.hasNext()) { Map.Entry entry = (Map.Entry) itr.next(); // get key Integer key = (Integer) entry.getKey(); // get value String value = (String) entry.getValue(); System.out.println("key:"+key+",value:"+value); } }复制代码
运行结果如下:
可以发现,继续往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();orMap<String,String> map=Collections.<String, String>emptyMap();//map1.put("1", "1"); 运行出错
如果你希望你的空map可以添加元素的,可以这样创建
Map map = new HashMap();8、有关于map的复制
有关于hashmap的复制,在日常开发中,使用也比较多。主要有=,clone,putAll,但是他们都是浅复制,使用的时候注意啦,可以看一下以下例子:
例子一,使用=复制一个map:
public class CopyMapAssignTest { public static void main(String[] args) { Map<Integer, User> userMap = new HashMap<>(); userMap.put(1, new User("jay", 26)); userMap.put(2, new User("fany", 25)); //Shallow clone Map<Integer, User> clonedMap = userMap; //Same as userMap System.out.println(clonedMap); System.out.println("\nChanges reflect in both maps \n"); //Change a value is clonedMap clonedMap.get(1).setName("test"); //Verify content of both maps System.out.println(userMap); System.out.println(clonedMap); }}
运行结果:
{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复制:
public class CopyCloneMapTest { public static void main(String[] args) { HashMap<Integer, User> userMap = new HashMap<>(); userMap.put(1, new User("jay", 26)); userMap.put(2, new User("fany", 25)); //Shallow clone HashMap<Integer, User> clonedMap = (HashMap<Integer, User>) userMap.clone(); //Same as userMap System.out.println(clonedMap); System.out.println("\nChanges reflect in both maps \n"); //Change a value is clonedMap clonedMap.get(1).setName("test"); //Verify content of both maps System.out.println(userMap); System.out.println(clonedMap); }}
运行结果:
{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操作
public class CopyPutAllMapTest { public static void main(String[] args) { HashMap<Integer, User> userMap = new HashMap<>(); userMap.put(1, new User("jay", 26)); userMap.put(2, new User("fany", 25)); //Shallow clone HashMap<Integer, User> clonedMap = new HashMap<>(); clonedMap.putAll(userMap); //Same as userMap System.out.println(clonedMap); System.out.println("\nChanges reflect in both maps \n"); //Change a value is clonedMap clonedMap.get(1).setName("test"); //Verify content of both maps System.out.println(userMap); System.out.println(clonedMap); }}
运行结果:
{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,实现深度复制的例子:
public class CopyDeepMapTest { public static void main(String[] args) { HashMap<Integer, User> userMap = new HashMap<>(); userMap.put(1, new User("jay", 26)); userMap.put(2, new User("fany", 25)); //Shallow clone Gson gson = new Gson(); String jsonString = gson.toJson(userMap); Type type = new TypeToken<HashMap<Integer, User>>(){}.getType(); HashMap<Integer, User> clonedMap = gson.fromJson(jsonString, type); //Same as userMap System.out.println(clonedMap); System.out.println("\nChanges DO NOT reflect in other map \n"); //Change a value is clonedMap clonedMap.get(1).setName("test"); //Verify content of both maps System.out.println(userMap); System.out.println(clonedMap); }}
运行结果:
{1=User{name='jay', age=26}, 2=User{name='fany', age=25}}Changes DO NOT reflect in other 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没有被改变,所以是深度复制。
作者:Jay_huaxiao
链接:
标签: #java mapisempty