亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java8中l(wèi)ambda表達式的應用及一些泛型相關知識

 更新時間:2017年01月04日 09:46:33   投稿:mrr  
這篇文章主要介紹了Java8中l(wèi)ambda表達式的應用及一些泛型相關知識的相關資料

語法部分就不寫了,我們直接拋出一個實際問題,看看java8的這些新特性究竟能給我們帶來哪些便利

順帶用到一些泛型編程,一切都是為了簡化代碼

場景:

一個數據類,用于記錄職工信息

public class Employee {
 public String name;
 public int age;
 public char sex;
 public String time;
 public int salary;
}

我們有一列此類數據

List<Employee> data = Arrays.asList(e1,e2,e3......)

現在有需求:將員工Employee按照姓名的首字母(假設均為英文名)進行分組:

那么我們要得到的結果應該是一個Map:char -> List<Employee> 這樣的映射關系

public static Map<Character, List<Employee>> groupByFirstChar(
 List<Employee> data){
  Map<Character, List<Employee>> result = new HashMap<>();
  for(Employee e : data){
   Character c = e.name.charAt(0);
   List<Employee> l = result.get(c);
   if(l == null){
    l = new ArrayList<>();
    result.put(c, l);
   }
   l.add(e);
  }
  return result;
}

代碼并不復雜,很快就可以完成,老板看你效率這么高,于是說,再按照工資分個組吧,5000以下的,5000~10000的 ...等

也不會太難,將key換一下,稍作邏輯處理即可

public static Map<String, List<Employee>> groupBySalary(List<Employee> data) {
 Map<String, List<Employee>> result = new HashMap<>();
 for (Employee e : data) {
  String key = separate(e.salary);
  List<Employee> l = result.get(key);
  if (l == null) {
   l = new ArrayList<>();
   result.put(key, l);
  }
  l.add(e);
 }
 return result;<br>}
private static String separate(int salary) {
 if (salary <= 5000) {
  return "5000以下";
 }
 if (salary <= 10000) {
   return "5000~10000";
 }
 if (salary <= 20000) {
  return "10000~20000";
 }
 return "20000以上"
}

然后老板又說了,按照員工的入職年份分下組吧。。。

這里就代碼就不寫了,稍作比較可以發(fā)現,無論怎么分組,唯一的變化是key值的選取方式,

第一次將Employee的name的第一字母作為key:

Employee e -> e.name.charAt(0)

第二次將Employee的salary按照方法separat轉換為String作為key:

Employee e -> separate(e.salary):String

以此類推

Employee e -> getYear(e.time):String

事實上第一次也可以將獲取首字母單獨寫成一個方法

Employee e -> getFirstChar(e.name):Character

為了看起來更美觀,可以講三個方法的參數都設置成Employee 方法體就不寫了 這里只列出參數和返回值

Employee e -> getFirstChar(e) : Character
Employee e -> separate(e) : String
Employee e -> getYear(e) : String

->的左邊為參數,:的右邊為返回值,->的右邊是方法的簽名

那么我們自然會想到將變化的部分抽取為參數,其他不變的部分抽取為方法體,那么就可以省去那些重復的代碼,顯然變化的部分就是上面列出的,將Employee e轉化成key的方法,但是我們知道java是不能把方法作為參數進行傳遞的。不過對于稍有經驗的程序猿來說這并不是問題,我們可以使用接口來實現我們的目的,同時又會遇到另一個問題,以上三個方法的返回值是不同的,因此我們要用到泛型:

public static <K> Map<K, List<Employee>> groupByKey(List<Employee> data, GetKey<K> getKey){
 Map<K, List<Employee>> result = new HashMap<>();
 for(Employee e : data) {
  K key = getKey.getKey(e);
  List<Employee> l = result.get(key);
  if (l == null) {
   l = new ArrayList<>();
   result.put(key, l);
  }
  l.add(e);
 }
  return result;
}
interface GetKey<K>{
 K getKey(Employee e);
}

那么上面的第一個需求就可以這樣實現

Map<Character, List<Employee>> result = groupByKey(data, new GetKey<Character>() {
   @Override
   public Character getKey(Employee e) {
    e.name.charAt(0);
   }
  });

第二個需求

Map<String, List<Employee>> result = groupByKey(list, new GetKey<String>() {
   @Override
   public String getKey(Employee e) {
    separate(e.salary);
   }
  });

可以發(fā)現,我們只需要更改泛型參數和匿名內部類的實現即可,唯一的問題恐怕是這么寫實在不太好看,而且很多例行公事的代碼,尤其體現在匿名內部類上。

事實上我們只關心這個匿名內部類的參數和返回值,其他部分僅僅是語法要求。

java8恰好為我們提供了很好的方式來避免復雜的例行公事的方式:lambda表達式,以上實現就可以寫成

Map<Character, List<Employee>> resultByFirstChar = groupByKey(list, e -> e.name.charAt(0));
Map<String, List<Employee>> resultBySalary = groupByKey(list, e -> separate(e.salary));

lambda表達式恰恰只表現出我們所關心的,參數和返回值,同時由于類型推斷,可以省去參數類型,具體語法這里就不介紹了,網上可以查到很多資料

extra:

如果你對泛型有不錯的了解的話,方法groupByKey還可以進一步抽象:

public static <K, E> Map<K, List<E>> groupBy(List<? extends E> data, Function<? super E, ? extends K> fun) {
 Map<K, List<E>> result = new HashMap<>();
 for(E e : data) {
  K k = fun.apply(e);<br>  List<E> l = result.get(k);
  if(l == null) {
   l = new ArrayList<>();
   result.put(k, l);
  }
  l.add(e);
 }
 return result;<br>
 }

我們將Employee這個類也抽取了,好處顯而易見

Function接口是java8新加入的接口:

@FunctionalInterface
public interface Function<T, R> {
 R apply(T t);
}

輸入一個T類型 返回R類型。泛型和函數式編程結合的很不錯,雖然java8的新特性被各種吐槽,但是能帶來好處總是好的,這給了我們更多的選擇。

有時間的話會介紹stream,java8的另一大利器

以上所述是小編給大家介紹的Java8中l(wèi)ambda表達式的應用及一些泛型相關知識,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

相關文章

  • Java雙重校驗鎖單例原理

    Java雙重校驗鎖單例原理

    大家好,本篇文章主要講的是Java雙重校驗鎖單例原理,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • 詳解spring security 配置多個AuthenticationProvider

    詳解spring security 配置多個AuthenticationProvider

    這篇文章主要介紹了詳解spring security 配置多個AuthenticationProvider ,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • Spring中的事務管理及實現方式解析

    Spring中的事務管理及實現方式解析

    這篇文章主要介紹了Spring中的事務管理及實現方式解析,Spring事務管理基于底層數據庫本身的事務處理機制,數據庫事務的基礎,是掌握Spring事務管理的基礎,這篇總結下Spring事務,需要的朋友可以參考下
    2024-01-01
  • 淺析Java中String與StringBuffer拼接的區(qū)別

    淺析Java中String與StringBuffer拼接的區(qū)別

    String拼接會創(chuàng)建一個新的String對象,存儲拼接后的字符串,StringBuffer拼接是直接在本身拼接,會即時刷新。下面通過本文給大家介紹Java中String與StringBuffer拼接的區(qū)別,感興趣的朋友一起看看吧
    2017-06-06
  • 詳解Java 對象序列化和反序列化

    詳解Java 對象序列化和反序列化

    本篇文章主要介紹了Java 對象序列化和反序列化,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java實現一鍵生成表controller,service,mapper文件

    Java實現一鍵生成表controller,service,mapper文件

    這篇文章主要為大家詳細介紹了如何利用Java語言實現一鍵生成表controller,service,mapper文件,文中的示例代碼講解詳細,需要的可以收藏一下
    2023-05-05
  • 如何理解Java線程池及其使用方法

    如何理解Java線程池及其使用方法

    線程池是首先創(chuàng)建一些線程,它們的集合稱為線程池。使用線程池可以提高性能,它在系統(tǒng)啟動時創(chuàng)建大量空閑的線程,程序將一個任務傳給線程池,它就會啟動一條線程來執(zhí)行這個任務,執(zhí)行結束以后,該線程并不會死亡,而是再次返回線程池中成為空閑狀態(tài),等待執(zhí)行下一個任務
    2021-06-06
  • IDEA插件(BindED)之查看class文件的十六進制

    IDEA插件(BindED)之查看class文件的十六進制

    這篇文章主要介紹了IDEA插件(BindED)之查看class文件的十六進制,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • IDEA新建springboot項目時未生成pom.xml文件的解決操作

    IDEA新建springboot項目時未生成pom.xml文件的解決操作

    這篇文章主要給大家介紹了關于IDEA新建springboot項目時未生成pom.xml文件的解決操作方法,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-02-02
  • java操作xml的方法匯總及解析

    java操作xml的方法匯總及解析

    這篇文章主要介紹了java操作xml的方法匯總及解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11

最新評論