有关于Java Map,应该掌握的8个问题

栏目: IT技术 · 发布时间: 4年前

内容简介:最近几天看了几篇有关于Java Map的外国博文,写得非常不错,所以整理了Java map 应该掌握的8个问题,都是日常开发司空见惯的问题,希望对大家有帮助;如果有不正确的地方,欢迎提出,万分感谢哈~本章节所有代码demo已上传github

前言

有关于Java Map,应该掌握的8个问题

最近几天看了几篇有关于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 list 
  List keyList = new ArrayList(map.keySet()); 
  // value list 
  List valueList = new ArrayList(map.values()); 
  // key-value list 
  List 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: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()); 
  }); 

实例代码:

  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实现

1.  SortedMap sortedMap = new TreeMap(new Comparator() { 
2.    @Override 
3.    public int compare(K k1, K k2) { 
4.      return k1.compareTo(k2); 
5.    } 
6.  }); 
7.  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: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()); 
    }); 

实例代码:

  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:huaxiao 
  key:2010,value:jay 
  key:1999,value:whx 

5、如何初始化一个静态/不可变的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:one 
  key:2,value:two 
  key: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); 
         } 
     } 
  
 } 

运行结果如下:

有关于Java Map,应该掌握的8个问题

可以发现,继续往map添加元素是会报错的,实现真正不可变的map。

6、HashMap, TreeMap, and Hashtable,ConcurrentHashMap的区别

有关于Java Map,应该掌握的8个问题

7、如何创建一个空map

如果map是不可变的,可以这样创建:

  Map map=Collections.emptyMap(); 
  or 
  Map<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 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 reflect in only one 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 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没有被改变,所以是深度复制。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

多任务下的数据结构与算法

多任务下的数据结构与算法

周伟明 / 华中科技 / 2006-4 / 58.00元

本书和传统同类书籍的区别是除了介绍基本的数据结构容器如栈、队列、链表、树、二叉树、红黑树、AVL树和图之外,引进了多任务;还介绍了将任意数据结构容器变成支持多任务的方法;另外,还增加了复合数据结构和动态数据结构等新内容的介绍。在复合数据结构中不仅介绍了哈希链表、哈希红黑树、哈希AVL树等容器,还介绍了复合数据结构的通用设计方法;在动态数据结构中主要介绍了动态环形队列、动态等尺寸内存管理算法。在内存......一起来看看 《多任务下的数据结构与算法》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具