最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java8中l(wèi)ambda表達(dá)式的應(yīng)用及一些泛型相關(guān)知識(shí)

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

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

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

場(chǎng)景:

一個(gè)數(shù)據(jù)類,用于記錄職工信息

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

我們有一列此類數(shù)據(jù)

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

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

那么我們要得到的結(jié)果應(yīng)該是一個(gè)Map:char -> List<Employee> 這樣的映射關(guān)系

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;
}

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

也不會(huì)太難,將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ā)現(xiàn),無論怎么分組,唯一的變化是key值的選取方式,

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

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

第二次將Employee的salary按照方法separat轉(zhuǎn)換為String作為key:

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

以此類推

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

事實(shí)上第一次也可以將獲取首字母單獨(dú)寫成一個(gè)方法

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

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

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

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

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

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);
}

那么上面的第一個(gè)需求就可以這樣實(shí)現(xiàn)

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

第二個(gè)需求

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

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

事實(shí)上我們只關(guān)心這個(gè)匿名內(nèi)部類的參數(shù)和返回值,其他部分僅僅是語法要求。

java8恰好為我們提供了很好的方式來避免復(fù)雜的例行公事的方式:lambda表達(dá)式,以上實(shí)現(xiàn)就可以寫成

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

lambda表達(dá)式恰恰只表現(xiàn)出我們所關(guān)心的,參數(shù)和返回值,同時(shí)由于類型推斷,可以省去參數(shù)類型,具體語法這里就不介紹了,網(wǎng)上可以查到很多資料

extra:

如果你對(duì)泛型有不錯(cuò)的了解的話,方法groupByKey還可以進(jìn)一步抽象:

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這個(gè)類也抽取了,好處顯而易見

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

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

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

有時(shí)間的話會(huì)介紹stream,java8的另一大利器

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

相關(guān)文章

  • AsyncHttpClient的TimeoutTimerTask連接池異步超時(shí)

    AsyncHttpClient的TimeoutTimerTask連接池異步超時(shí)

    這篇文章主要為大家介紹了AsyncHttpClient的TimeoutTimerTask連接池異步超時(shí)源碼流程解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • 解析java.library.path和LD_LIBRARY_PATH的介紹與區(qū)別

    解析java.library.path和LD_LIBRARY_PATH的介紹與區(qū)別

    這篇文章主要介紹了java.library.path和LD_LIBRARY_PATH的介紹與區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • SSH框架網(wǎng)上商城項(xiàng)目第7戰(zhàn)之整合Struts2和Json

    SSH框架網(wǎng)上商城項(xiàng)目第7戰(zhàn)之整合Struts2和Json

    SSH框架網(wǎng)上商城項(xiàng)目第7戰(zhàn)之整合Struts2和Json,打通EasyUI和Struts2之間的交互,感興趣的小伙伴們可以參考一下
    2016-05-05
  • SpringBoot使用責(zé)任鏈模式優(yōu)化業(yè)務(wù)邏輯中的if-else代碼

    SpringBoot使用責(zé)任鏈模式優(yōu)化業(yè)務(wù)邏輯中的if-else代碼

    在開發(fā)過程中,我們經(jīng)常會(huì)遇到需要根據(jù)不同的條件執(zhí)行不同的邏輯的情況,我們可以考慮使用責(zé)任鏈模式來優(yōu)化代碼結(jié)構(gòu),使得代碼更加清晰、可擴(kuò)展和易于維護(hù)
    2023-06-06
  • Docker和?Containerd?的區(qū)別解析

    Docker和?Containerd?的區(qū)別解析

    containerd?是一個(gè)來自?Docker?的高級(jí)容器運(yùn)行時(shí),并實(shí)現(xiàn)了?CRI?規(guī)范,它是從?Docker?項(xiàng)目中分離出來,之后?containerd?被捐贈(zèng)給云原生計(jì)算基金會(huì)(CNCF)為容器社區(qū)提供創(chuàng)建新容器解決方案的基礎(chǔ),這篇文章主要介紹了Docker和?Containerd?的區(qū)別,需要的朋友可以參考下
    2024-03-03
  • Mybatis Plus插件三種方式的逆向工程的使用

    Mybatis Plus插件三種方式的逆向工程的使用

    這篇文章主要介紹了Mybatis Plus插件三種方式的逆向工程的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 詳解SpringBoot中如何使用Reactor模型

    詳解SpringBoot中如何使用Reactor模型

    Reactor模型主要提供了一種在Java虛擬機(jī)上構(gòu)建非阻塞應(yīng)用的方式,這種方式使用了響應(yīng)式編程原理,通過響應(yīng)式流標(biāo)準(zhǔn)來實(shí)現(xiàn),下面我們就來看看它在SpringBoot中是如何使用的吧
    2024-04-04
  • JAVA如何解決并發(fā)問題

    JAVA如何解決并發(fā)問題

    這篇文章主要介紹了JAVA如何解決并發(fā)問題的處理方法,文中講解的非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • java中的分布式事務(wù)解決方式

    java中的分布式事務(wù)解決方式

    分布式事務(wù)是分布式系統(tǒng)中確保數(shù)據(jù)一致性的重要機(jī)制,它涉及多個(gè)數(shù)據(jù)源或參與者,要么所有操作全部成功,要么全部失敗,常見的解決方案包括2PC(兩階段提交協(xié)議)、3PC(三階段提交協(xié)議)和TCC(Try-Confirm-Cancel),2PC雖然簡(jiǎn)單但存在單點(diǎn)故障等問題
    2024-09-09
  • Spring MVC中自定義攔截器的實(shí)例講解

    Spring MVC中自定義攔截器的實(shí)例講解

    下面小編就為大家?guī)硪黄猄pring MVC中自定義攔截器的實(shí)例講解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08

最新評(píng)論

漯河市| 陇南市| 宁武县| 乐亭县| 平顺县| 酒泉市| 蒙自县| 五指山市| 武邑县| 武威市| 东台市| 玉屏| 吴忠市| 潞西市| 绍兴市| 蓬溪县| 云浮市| 卢湾区| 台湾省| 徐闻县| 玉门市| 景宁| 平原县| 富裕县| 永顺县| 玉门市| 英超| 嵊泗县| 贵州省| 聂拉木县| 平凉市| 昌平区| 新闻| 珲春市| 郑州市| 双峰县| 光山县| 鄢陵县| 平阴县| 北海市| 商洛市|