成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 8中Map騷操作之merge()的用法

開發 后端
Java 8 最大的特性無異于更多地面向函數,比如引入了 lambda等,可以更好地進行函數式編程。前段時間無意間發現了 map.merge() 方法,感覺還是很好用的,此文簡單做一些相關介紹。

[[324081]]

Java 8 最大的特性無異于更多地面向函數,比如引入了 lambda等,可以更好地進行函數式編程。前段時間無意間發現了 map.merge() 方法,感覺還是很好用的,此文簡單做一些相關介紹。首先我們先看一個例子。

merge() 怎么用?

假設我們有這么一段業務邏輯,我有一個學生成績對象的列表,對象包含學生姓名、科目、科目分數三個屬性,要求求得每個學生的總成績。加入列表如下:

  1. private List<StudentScore> buildATestList() { 
  2.         List<StudentScore> studentScoreList = new ArrayList<>(); 
  3.         StudentScore studentScore1 = new StudentScore() {{ 
  4.             setStuName("張三"); 
  5.             setSubject("語文"); 
  6.             setScore(70); 
  7.         }}; 
  8.         StudentScore studentScore2 = new StudentScore() {{ 
  9.             setStuName("張三"); 
  10.             setSubject("數學"); 
  11.             setScore(80); 
  12.         }}; 
  13.         StudentScore studentScore3 = new StudentScore() {{ 
  14.             setStuName("張三"); 
  15.             setSubject("英語"); 
  16.             setScore(65); 
  17.         }}; 
  18.         StudentScore studentScore4 = new StudentScore() {{ 
  19.             setStuName("李四"); 
  20.             setSubject("語文"); 
  21.             setScore(68); 
  22.         }}; 
  23.         StudentScore studentScore5 = new StudentScore() {{ 
  24.             setStuName("李四"); 
  25.             setSubject("數學"); 
  26.             setScore(70); 
  27.         }}; 
  28.         StudentScore studentScore6 = new StudentScore() {{ 
  29.             setStuName("李四"); 
  30.             setSubject("英語"); 
  31.             setScore(90); 
  32.         }}; 
  33.         StudentScore studentScore7 = new StudentScore() {{ 
  34.             setStuName("王五"); 
  35.             setSubject("語文"); 
  36.             setScore(80); 
  37.         }}; 
  38.         StudentScore studentScore8 = new StudentScore() {{ 
  39.             setStuName("王五"); 
  40.             setSubject("數學"); 
  41.             setScore(85); 
  42.         }}; 
  43.         StudentScore studentScore9 = new StudentScore() {{ 
  44.             setStuName("王五"); 
  45.             setSubject("英語"); 
  46.             setScore(70); 
  47.         }}; 
  48.  
  49.         studentScoreList.add(studentScore1); 
  50.         studentScoreList.add(studentScore2); 
  51.         studentScoreList.add(studentScore3); 
  52.         studentScoreList.add(studentScore4); 
  53.         studentScoreList.add(studentScore5); 
  54.         studentScoreList.add(studentScore6); 
  55.         studentScoreList.add(studentScore7); 
  56.         studentScoreList.add(studentScore8); 
  57.         studentScoreList.add(studentScore9); 
  58.  
  59.         return studentScoreList; 
  60.     } 

我們先看一下常規做法:

  1.  ObjectMapper objectMapper = new ObjectMapper(); 
  2.         List<StudentScore> studentScoreList = buildATestList(); 
  3.  
  4.         Map<String, Integer> studentScoreMap = new HashMap<>(); 
  5.         studentScoreList.forEach(studentScore -> { 
  6.             if (studentScoreMap.containsKey(studentScore.getStuName())) { 
  7.                 studentScoreMap.put(studentScore.getStuName(),  
  8.                                     studentScoreMap.get(studentScore.getStuName()) + studentScore.getScore()); 
  9.             } else { 
  10.                 studentScoreMap.put(studentScore.getStuName(), studentScore.getScore()); 
  11.             } 
  12.         }); 
  13.  
  14.         System.out.println(objectMapper.writeValueAsString(studentScoreMap)); 
  15.  
  16. // 結果如下: 
  17. // {"李四":228,"張三":215,"王五":235} 

然后再看一下 merge() 是怎么做的:

  1.  Map<String, Integer> studentScoreMap2 = new HashMap<>(); 
  2.         studentScoreList.forEach(studentScore -> studentScoreMap2.merge( 
  3.           studentScore.getStuName(), 
  4.           studentScore.getScore(), 
  5.           Integer::sum)); 
  6.  
  7.         System.out.println(objectMapper.writeValueAsString(studentScoreMap2)); 
  8.  
  9. // 結果如下: 
  10. // {"李四":228,"張三":215,"王五":235} 

merge() 簡介

merge() 可以這么理解:它將新的值賦值到 key (如果不存在)或更新給定的key 值對應的 value,其源碼如下:

  1. default V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 
  2.        Objects.requireNonNull(remappingFunction); 
  3.        Objects.requireNonNull(value); 
  4.        V oldValue = this.get(key); 
  5.        V newValue = oldValue == null ? value : remappingFunction.apply(oldValue, value); 
  6.        if (newValue == null) { 
  7.            this.remove(key); 
  8.        } else { 
  9.            this.put(key, newValue); 
  10.        } 
  11.  
  12.        return newValue; 
  13.    } 

我們可以看到原理也是很簡單的,該方法接收三個參數,一個 key 值,一個 value,一個 remappingFunction ,如果給定的key不存在,它就變成了 put(key, value) 。

但是,如果 key 已經存在一些值,我們 remappingFunction 可以選擇合并的方式,然后將合并得到的 newValue 賦值給原先的 key。

使用場景

這個使用場景相對來說還是比較多的,比如分組求和這類的操作,雖然 stream 中有相關 groupingBy() 方法,但如果你想在循環中做一些其他操作的時候,merge() 還是一個挺不錯的選擇的。

其他

除了 merge() 方法之外,我還看到了一些Java 8 中 map 相關的其他方法,比如 putIfAbsent 、compute() 、computeIfAbsent() 、computeIfPresent,這些方法我們看名字應該就知道是什么意思了,故此處就不做過多介紹了,感興趣的可以簡單閱讀一下源碼(都還是挺易懂的),這里我們貼一下 compute()(Map.class) 的源碼,其返回值是計算后得到的新值:

  1. default V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 
  2.        Objects.requireNonNull(remappingFunction); 
  3.        V oldValue = this.get(key); 
  4.        V newValue = remappingFunction.apply(key, oldValue); 
  5.        if (newValue == null) { 
  6.            if (oldValue == null && !this.containsKey(key)) { 
  7.                return null
  8.            } else { 
  9.                this.remove(key); 
  10.                return null
  11.            } 
  12.        } else { 
  13.            this.put(key, newValue); 
  14.            return newValue; 
  15.        } 
  16.    } 

總結

本文簡單介紹了一下 Map.merge() 的方法,除此之外,Java 8 中的 HashMap 實現方法使用了 TreeNode 和 紅黑樹,在源碼閱讀上可能有一點難度,不過原理上還是相似的,compute() 同理。所以,源碼肯定是要看的,不懂的地方多讀多練自然就理解了。

鏈接

參考:

https://www.jianshu.com/p/68e6b30410b0

測試代碼地址:

https://github.com/lq920320/algorithm-java-test/blob/master/src/test/java/other/MapMethodsTest.java 

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2021-08-16 08:12:04

SQLMerge用法

2023-09-06 11:31:24

MERGE用法SQL

2020-04-03 13:43:23

Python列表推導式字典推導式

2010-11-04 11:17:42

DB2 Merge語句

2020-05-27 11:30:54

Chrome DevT前端命令

2022-08-18 15:03:13

并發編程

2020-03-16 08:41:00

互聯網疫情公司

2021-09-15 16:05:41

map.putJavaMap

2022-04-25 08:43:47

pandas代碼Python

2010-04-26 11:37:25

Oracle merg

2024-11-13 16:19:12

2025-03-25 10:49:13

2020-03-11 20:11:06

電腦騷操作AMD

2021-08-05 18:21:29

Autowired代碼spring

2023-12-21 14:43:30

Python字典

2021-12-14 09:12:40

Gopher結構體接口

2014-04-11 12:49:00

Java8Java8教程

2020-11-23 11:30:00

IDEA技巧開發

2021-11-03 17:04:11

攔截器操作Servlet

2023-07-26 07:41:27

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 夜夜夜夜草| 精品视频久久久 | 日韩一二区在线观看 | www97影院| 国产精品 欧美精品 | 国产精品1区2区 | 久久九九色 | 日日干夜夜操 | 黄 色 毛片免费 | 亚洲综合一区二区三区 | 精品九九九 | 亚洲精品1区| 国产97碰免费视频 | 黄色网页在线 | 欧美一二三区 | 天天躁日日躁狠狠躁白人 | 视频一区二区中文字幕日韩 | 鸡毛片| 色婷婷综合久久久中字幕精品久久 | 高清久久久 | 欧美中文在线 | 午夜免费视频 | av中文字幕在线 | 亚洲国产成人精品久久 | 亚洲精品中文在线 | 亚洲一区二区电影在线观看 | 久久久久国产 | 日韩av成人 | 国产成人一区二区三区 | 亚洲福利在线视频 | 成人精品一区亚洲午夜久久久 | 91色视频在线观看 | 国产高清在线精品一区二区三区 | 日韩一区二区视频 | 91精品国产91久久久久久 | 九九av| 久久伊人影院 | 欧美精品一区二区三区在线 | 欧美成人激情 | 久久99国产精一区二区三区 | 91精品国产综合久久久久久丝袜 |