Java 8 Lambda表達式使用總結

Lambda表達式

示例實體類

@Data
public class User{
	private int id;  //id
	private Double score;  //成績
	private String name;  //姓名
	private String sex;  //性別
	private BigDecimal property;//財產
	private Date birthDay;  //生日
}

示例Map<String,object> map

Map<String,object> map = new HashMap<>();
map.put("id",1);
map.put("name","hucong");
map.put("age",23);
map.put("score",100.0);

1、通過條件過濾filter()

  • 獲取男性用戶集合:List< User> list = userList.stream().filter(t->t.getSex().equals("female")).collect(Collectors.toList());
    其他參考:list中快速進行數據篩選
  • 補充List<Map<String,Object>> listMap處理:
    • ObjectToInteget:
      獲取年齡大於18歲的用戶的集合:listMap = listMap.stream().filter(t->StringUtils.toInteger(t.get("age"))>18).collect(Collectors.toList());
    • ObjectToString:
      獲取姓名爲“hucong”的用戶的集合::listMap = listMap.stream().filter(t->t.get("name").equals("hucong")).collect(Collectors.toList());

2、獲取list某個字段組裝新list方法map()

  • 得到用戶姓名組裝成新的集合:List< String> list = userList.stream().map(User::getName).collect(Collectors.toList());
  • 補充List<Map<String,Object>> listMap處理:
    獲取用戶姓名的集合的集合:List< String> list = listMap.map(t->t.get("name").toString).collect(Collectors.toList());

3、去重distinct() [指定條件去重見標號9]

distinct()返回由該流的不同元素組成的流。distinct()是Stream接口的方法。distinct()使用hashCode()和equals()方法來獲取不同的元素。因此,我們的類必須實現hashCode()和equals()方法。如果distinct()正在處理有序流,那麼對於重複元素,將保留以遭遇順序首先出現的元素,並且以這種方式選擇不同元素是穩定的。在無序流的情況下,不同元素的選擇不一定是穩定的,是可以改變的。distinct()執行有狀態的中間操作。在有序流的並行流的情況下,保持distinct()的穩定性是需要很高的代價的,因爲它需要大量的緩衝開銷。如果我們不需要保持遭遇順序的一致性,那麼我們應該可以使用通過BaseStream.unordered()方法實現的無序流。

4、單字段多字段排序sort()和stream.sorted()

  • sort()

  • 按成績單字段排序:List< User> list = userList.sort(Comparator.comparing(User::getScore));
  • 按成績和id多字段排序:List< User> list = userList.sort(Comparator.comparing(User::getScore).thenComparing(User::getId));
  • 按成績,如果成績中有null值則倒序排列:List< User> list = userList.sort(Comparator.comparing(User::getScore,Comparator.nullsLast(Comparator.naturalOrder())));
  • stream.sorted()

  • 按成績升序排列:List< User> list = userList.stream().sorted(Comparator.comparing(User::getScore)).collect(toList());
  • 按成績降序排列:List< User> list = userList.stream().sorted(Comparator.comparing(User::getScore)).reversed().collect(toList());
  • 補充List<Map<String,Object>> listMap處理:
    按用戶的年齡從大到小排序:
    • 排序:listMap = listMapstream().sorted(Comparator.comparing(t->StringUtils.toInteger(t.get("age")))).collect(Collectors.toList());
    • 反轉:(因爲默認是從下到大排,所以需要顛倒):Collections.reverse(listMap);
  • 延伸:Java 8 Comparator nullsFirst naturalOrder困惑

5、彙總求和sum()

  • 基本數據類型,如int:int sumScore = userList.strem().mapToInt(User::getScore).sum();
  • 其他數據類型,如BigDecimal:BigDecimal totalProperty = userList.stream().map(User::getProperty).reduce(BigDecimal.ZERO,BigDecimal::add);
  • 補充List<Map<String,Object>> listMap處理:
    求用戶總分:Double total = materialByYear.stream().mapToDouble(t->StringUtils.toDouble(t.get("score"))).sum();

6、找最值.min

  • 找到年齡最大的學生生日:Date maxBirthDay = userList.stream().map(User::getBirthday).max(Date::compareTo).get();
  • 找到最低分:Double minScore = userList.stream().min(Comparator.comparingDouble(User::getScore)).get();

7、list轉map

  • 將User中的姓名作爲鍵名,對應實體作爲鍵值,組成新的Map:Map< String,User> map = list.stream().collect(Collectors.toMap(User::getName,t->t));
  • 將User中的姓名作爲鍵名,對應實體作爲鍵值,組成新的Map,如果有重複鍵名則保留先進入map的那一個:Map< String,User> map = list.stream().collect(Collectors.toMap(User::getName,t -> t,(k1,k2)->k1));
    //注:toMap 如果集合對象有重複的key,會報錯Duplicate key …Name可能重複。可以用 (k1,k2)->k1 來設置,如果有重複的key,則保留key1,捨棄key2
    //如果想得到姓名的鍵值列表:Set< String> userNames = map.keySet();
    //如果想比對某一個名稱是否在已存在map中:if(map.containKey(user.getName())){printf("已存在該用戶")}
  • 補充List<Map<String,Object>> listMap處理:
    將map中“id”字段作爲鍵名,對應的map作爲鍵值:
    Map<String,Map<String,Object>> newMap = mapList.stream().collect(Collectors.toMap(t->t.get("id").toString(),t->t));

8、通過指定字段進行分組Collectors.groupingBy()

  • 根據性別進行分組:Map<String, List< User>> groupBySex = userList.stream().collect(Collectors.groupingBy(User::getSex));
  • 補充List<Map<String,Object>> listMap處理:
    根據性別分組:Map<String,List<Map<String,Object>>> groupBy = listMap.stream().collect(Collectors.groupingBy(t->t.get("sex").toString()));

9、指定字段或者條件進行去重

  • 根據分數去重實體:List< User> list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getScore))),ArrayList::new));
  • 如果兩個對象分數和性別一致,則去重:List< User> list = list.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()->new TreeSet<>(Comparator.comparing(t->t.getName()+t.getSex()))),ArrayList::new));

10、其他:

  • List< Integer>轉成List< String>
    List< String> list = intList.stream().map(t->String.format("%s",t)).collect(toList());
  • List< Integer>正、倒序
    正序排列:Collections.sort(list);
    倒序排列:list.sort(Comparator.revseOrder());
  • List< String>中保存的爲成績信息,對成績信息進行求和計數等操作
    IntSummaryStatistics stats = list.stream().mapToDouble((t)->t).summaryStatustics();
    最大值:stats.getMax();
    最小值:stats.getMin();
    求和:stats.getSum();
    平均數:stats.getAverage();
    計數:stats.getCount();
    toString():stats.toString();
    
  • 通過複雜條件過濾list中的元素
    需求:有一個用戶信息List< User>list集合和一個Id集合List< Integer>listInt,需要將在list中id在集合listInt中的對象去除:
    //首先將list轉成id-entity的鍵值對(id不可能重複,所以不考慮鍵名重複的情況)
    Map< Integer,User> map = list.stream().collect(Collectors.toMap(User::getId,t->t));
    //得到鍵值集合
    Set< Integer> ids = map.keySet();
    //通過set的contains()方法判定
    for(Integer i:listInt){
    	if(ids.contains(i)){
    		list.remove(map.get(i));
    	}
    }
    

參考資料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章