国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

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

2019-11-26 13:19:53
字體:
供稿:網(wǎng)友

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

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

場景:

一個數(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è)均為英文名)進行分組:

那么我們要得到的結(jié)果應(yīng)該是一個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ù)雜,很快就可以完成,老板看你效率這么高,于是說,再按照工資分個組吧,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ā)現(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

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

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

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

Employee e -> getFirstChar(e) : CharacterEmployee e -> separate(e) : StringEmployee e -> getYear(e) : String

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

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

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

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

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

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

java8恰好為我們提供了很好的方式來避免復(fù)雜的例行公事的方式:lambda表達式,以上實現(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表達式恰恰只表現(xiàn)出我們所關(guān)心的,參數(shù)和返回值,同時由于類型推斷,可以省去參數(shù)類型,具體語法這里就不介紹了,網(wǎng)上可以查到很多資料

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新加入的接口:

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

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

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

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

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 安化县| 内乡县| 长白| 浠水县| 平凉市| 堆龙德庆县| 通州区| 鲜城| 皮山县| 大港区| 桂平市| 红河县| 泸西县| 青神县| 伊宁县| 扎囊县| 泰安市| 昔阳县| 饶河县| 蒙城县| 大庆市| 常熟市| 平谷区| 蒙阴县| 广东省| 甘洛县| 中西区| 四子王旗| 益阳市| 桃江县| 三门峡市| 百色市| 进贤县| 普陀区| 镇康县| 宁南县| 蒲江县| 乌鲁木齐市| 宝应县| 商城县| 芦山县|