Java中Lambda表達式的使用_第1頁
Java中Lambda表達式的使用_第2頁
Java中Lambda表達式的使用_第3頁
Java中Lambda表達式的使用_第4頁
Java中Lambda表達式的使用_第5頁
已閱讀5頁,還剩6頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

Java中Lambda表達式的使用Lambda表達式概述Lambda表達式的本質只是一個"語法糖",由編譯器推斷并幫我們轉換包裝為常規的代碼,因此我們可以使用更少的代碼來實現同樣的功能。本人建議不要亂用,因為這就和某些很高級的黑客寫的代碼一樣,簡潔,難懂,難以調試,維護人員想罵娘。Lambda表達式是JavaSE8中一個重要的新特性。lambda表達式允許我們通過表達式來代替功能接口。lambda表達式就和方法一樣,它提供了一個正常的參數列表和一個使用這些參數的主體(body,可以是一個表達式或一個代碼塊)。Lambda表達式還增強了集合庫。JavaSE8添加了2個對集合數據進行批量操作的包:java.util.function包以及java.util.stream包。流(stream)就如同迭代器(iterator),但附加了許多額外的功能。總的來說,lambda表達式和stream是自Java語言添加泛型(Generics)和注解(annotation)以來最大的變化。在本文中,我們將從簡單到復雜的示例中見認識lambda表達式和stream的強悍。環境準備如果還沒有安裝Java8,那么我們應該先安裝才能使用lambda和stream(譯者建議在虛擬機中安裝,測試使用)。像NetBeans和IntelliJIDEA一類的工具和IDE就支持Java8特性,包括lambda表達式,可重復的注解,緊湊的概要文件和其他特性。Lambda表達式的語法基本語法:(parameters)->expression或(parameters)->{statements;}Javalambda表達式的簡單例子://1.不需要參數,返回值為5()->5//2.接收一個參數(數字類型),返回其2倍的值x->2*x//3.接受2個參數(數字),并返回他們的差值(x,y)->x–y//4.接收2個int型整數,返回他們的和(intx,inty)->x+y//5.接受一個string對象,并在控制臺打印,不返回任何值(看起來像是返回void)(Strings)->System.out.print(s)基本的Lambda例子現在,我們已經知道什么是lambda表達式,讓我們先從一些基本的例子開始。在本節中,我們將看到lambda表達式如何影響我們編碼的方式。假設有一個玩家List,程序員可以使用for語句("for循環")來遍歷,在JavaSE8中可以轉換為另一種形式:String[]atp={"RafaelNadal","NovakDjokovic","StanislasWawrinka","DavidFerrer","RogerFederer","AndyMurray","TomasBerdych","JuanMartinDelPotro"};List<String>players=Arrays.asList(atp);//以前的循環方式for(Stringplayer:players){System.out.print(player+";");}//使用lambda表達式以及函數操作(functionaloperation)players.forEach((player)->System.out.print(player+";"));//在Java8中使用雙冒號操作符(doublecolonoperator)players.forEach(System.out::println);正如我們看到的,lambda表達式可以將我們的代碼縮減到一行。另一個例子是在圖形用戶界面程序中,匿名類可以使用lambda表達式來代替。同樣,在實現Runnable接口時也可以這樣使用://使用匿名內部類btn.setOnAction(newEventHandler<ActionEvent>(){@Overridepublicvoidhandle(ActionEventevent){System.out.println("HelloWorld!");}});//或者使用lambdaexpressionbtn.setOnAction(event->System.out.println("HelloWorld!"));使用lambdas來實現Runnable接口的示例:Runnable就是一個函數式接口:他只有一個方法run()方法。1、因為run()方法沒有參數,所以->前面的()中不需要聲明形參2、run返回的是void,所以不需要return。3、->后面寫的代碼其實就是定義在run方法內的代碼。因為此處代碼只有一行,所以{}也可以省略。如果此處多與一行,則無法省略。//1.1使用匿名內部類newThread(newRunnable(){@Overridepublicvoidrun(){System.out.println("Helloworld!");}}).start();//1.2使用lambdaexpressionnewThread(()->System.out.println("Helloworld!")).start();//2.1使用匿名內部類Runnablerace1=newRunnable(){@Overridepublicvoidrun(){System.out.println("Helloworld!");}};//2.2使用lambdaexpressionRunnablerace2=()->System.out.println("Helloworld!");//直接調用run方法(沒開新線程哦!)race1.run();race2.run();Runnable的lambda表達式,使用塊格式,將五行代碼轉換成單行語句。接下來,在下一節中我們將使用lambdas對集合進行排序。使用Lambdas排序集合在Java中,Comparator類被用來排序集合。在下面的例子中,我們將根據球員的name,surname,name長度以及最后一個字母。和前面的示例一樣,先使用匿名內部類來排序,然后再使用lambda表達式精簡我們的代碼。在第一個例子中,我們將根據name來排序list。使用舊的方式,代碼如下所示:String[]players={"RafaelNadal","NovakDjokovic","StanislasWawrinka","DavidFerrer","RogerFederer","AndyMurray","TomasBerdych","JuanMartinDelPotro","RichardGasquet","JohnIsner"};//1.1使用匿名內部類根據name排序playersArrays.sort(players,newComparator<String>(){@Overridepublicintcompare(Strings1,Strings2){return(pareTo(s2));}});使用lambdas,可以通過下面的代碼實現同樣的功能://1.2使用lambdaexpression排序playersComparator<String>sortByName=(Strings1,Strings2)->(pareTo(s2));Arrays.sort(players,sortByName);//1.3也可以采用如下形式:Arrays.sort(players,(Strings1,Strings2)->(pareTo(s2)));其他的排序如下所示。和上面的示例一樣,代碼分別通過匿名內部類和一些lambda表達式來實現Comparator://1.1使用匿名內部類根據surname排序playersArrays.sort(players,newComparator<String>(){@Overridepublicintcompare(Strings1,Strings2){return(s1.substring(s1.indexOf("")).compareTo(s2.substring(s2.indexOf(""))));}});//1.2使用lambdaexpression排序,根據surnameComparator<String>sortBySurname=(Strings1,Strings2)->(s1.substring(s1.indexOf("")).compareTo(s2.substring(s2.indexOf(""))));Arrays.sort(players,sortBySurname);//1.3或者這樣,懷疑原作者是不是想錯了,括號好多...Arrays.sort(players,(Strings1,Strings2)->(s1.substring(s1.indexOf("")).compareTo(s2.substring(s2.indexOf("")))));//2.1使用匿名內部類根據namelenght排序playersArrays.sort(players,newComparator<String>(){@Overridepublicintcompare(Strings1,Strings2){return(s1.length()-s2.length());}});//2.2使用lambdaexpression排序,根據namelenghtComparator<String>sortByNameLenght=(Strings1,Strings2)->(s1.length()-s2.length());Arrays.sort(players,sortByNameLenght);//2.3orthisArrays.sort(players,(Strings1,Strings2)->(s1.length()-s2.length()));//3.1使用匿名內部類排序players,根據最后一個字母Arrays.sort(players,newComparator<String>(){@Overridepublicintcompare(Strings1,Strings2){return(s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1));}});//3.2使用lambdaexpression排序,根據最后一個字母Comparator<String>sortByLastLetter=(Strings1,Strings2)->(s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1));Arrays.sort(players,sortByLastLetter);//3.3orthisArrays.sort(players,(Strings1,Strings2)->(s1.charAt(s1.length()-1)-s2.charAt(s2.length()-1)));就是這樣,簡潔又直觀。在下一節中我們將探索更多lambdas的能力,并將其與stream結合起來使用。使用Lambdas和StreamsStream是對集合的包裝,通常和lambda一起使用。使用lambdas可以支持許多操作,如map,filter,limit,sorted,count,min,max,sum,collect等等。同樣,Stream使用懶運算,他們并不會真正地讀取所有數據,遇到像getFirst()這樣的方法就會結束鏈式語法。在接下來的例子中,我們將探索lambdas和streams能做什么。我們創建了一個Person類并使用這個類來添加一些數據到list中,將用于進一步流操作。Person只是一個簡單的POJO類:publicclassPerson{privateStringfirstName,lastName,job,gender;privateintsalary,age;publicPerson(StringfirstName,StringlastName,Stringjob,Stringgender,intage,intsalary){this.firstName=firstName;this.lastName=lastName;this.gender=gender;this.age=age;this.job=job;this.salary=salary;}//GetterandSetter//.....}接下來,我們將創建兩個list,都用來存放Person對象:List<Person>javaProgrammers=newArrayList<Person>(){{add(newPerson("Elsdon","Jaycob","Javaprogrammer","male",43,2000));add(newPerson("Tamsen","Brittany","Javaprogrammer","female",23,1500));add(newPerson("Floyd","Donny","Javaprogrammer","male",33,1800));add(newPerson("Sindy","Jonie","Javaprogrammer","female",32,1600));add(newPerson("Vere","Hervey","Javaprogrammer","male",22,1200));add(newPerson("Maude","Jaimie","Javaprogrammer","female",27,1900));add(newPerson("Shawn","Randall","Javaprogrammer","male",30,2300));add(newPerson("Jayden","Corrina","Javaprogrammer","female",35,1700));add(newPerson("Palmer","Dene","Javaprogrammer","male",33,2000));add(newPerson("Addison","Pam","Javaprogrammer","female",34,1300));}};List<Person>phpProgrammers=newArrayList<Person>(){{add(newPerson("Jarrod","Pace","PHPprogrammer","male",34,1550));add(newPerson("Clarette","Cicely","PHPprogrammer","female",23,1200));add(newPerson("Victor","Channing","PHPprogrammer","male",32,1600));add(newPerson("Tori","Sheryl","PHPprogrammer","female",21,1000));add(newPerson("Osborne","Shad","PHPprogrammer","male",32,1100));add(newPerson("Rosalind","Layla","PHPprogrammer","female",25,1300));add(newPerson("Fraser","Hewie","PHPprogrammer","male",36,1100));add(newPerson("Quinn","Tamara","PHPprogrammer","female",21,1000));add(newPerson("Alvin","Lance","PHPprogrammer","male",38,1600));add(newPerson("Evonne","Shari","PHPprogrammer","female",40,1800));}};現在我們使用forEach方法來迭代輸出上述列表:System.out.println("所有程序員的姓名:");javaProgrammers.forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));phpProgrammers.forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));我們同樣使用forEach方法,增加程序員的工資5%:System.out.println("給程序員加薪5%:");Consumer<Person>giveRaise=e->e.setSalary(e.getSalary()/100*5+e.getSalary());javaProgrammers.forEach(giveRaise);phpProgrammers.forEach(giveRaise);另一個有用的方法是過濾器filter(),讓我們顯示月薪超過1400美元的PHP程序員:System.out.println("下面是月薪超過$1,400的PHP程序員:")phpProgrammers.stream().filter((p)->(p.getSalary()>1400)).forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));我們也可以定義過濾器,然后重用它們來執行其他操作://定義filtersPredicate<Person>ageFilter=(p)->(p.getAge()>25);Predicate<Person>salaryFilter=(p)->(p.getSalary()>1400);Predicate<Person>genderFilter=(p)->("female".equals(p.getGender()));System.out.println("下面是年齡大于24歲且月薪在$1,400以上的女PHP程序員:");phpProgrammers.stream().filter(ageFilter).filter(salaryFilter).filter(genderFilter).forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));//重用filtersSystem.out.println("年齡大于24歲的女性Javaprogrammers:");javaProgrammers.stream().filter(ageFilter).filter(genderFilter).forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));使用limit方法,可以限制結果集的個數:System.out.println("最前面的3個Javaprogrammers:");javaProgrammers.stream().limit(3).forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));System.out.println("最前面的3個女性Javaprogrammers:");javaProgrammers.stream().filter(genderFilter).limit(3).forEach((p)->System.out.printf("%s%s;",p.getFirstName(),p.getLastName()));排序呢?我們在stream中能處理嗎?答案是肯定的。在下面的例子中,我們將根據名字和薪水排序Java程序員,放到一個list中,然后顯示列表:System.out.println("根據name排序,并顯示前5個Javaprogrammers:");List<Person>sortedJavaProgrammers=javaProgrammers.stream().sorted((p,p2)->(p.getFirstName().compareTo(p2.getFirstName()))).limit(5).collect(toList());sortedJavaProgrammers.forEach((p)->System.out.printf("%s%s;%n",p.getFirstName(),p.getLastName()));System.out.println("根據salary排序Javaprogrammers:");sortedJavaProgrammers=javaProgrammers.stream().sorted((p,p2)->(p.getSalary()-p2.getSalary())).collect(toList());sortedJavaProgrammers.forEach((p)->System.out.printf("%s%s;%n",p.getFirstName(),p.getLastName()));如果我們只對最低和最高的薪水感興趣,比排序后選擇第一個/最后一個更快的是min和max方法:System.out.println("工資最低的Javaprogrammer:");Personpers=javaProgrammers.stream().min((p1,p2)->(p1.getSalary()-p2.getSalary())).get()System.out.printf("Name:%s%s;Salary:$%,d.",pers.getFirstName(),pers.getLastName(),pers.getSalary())System.out.println("工資最高的Javaprogrammer:");Personperson=javaProgrammers.stream().max((p,p2)->(p.getSalary()-p2.getSalary())).get()System.out.printf("Name:%s%s;Salary:$%,d.",person.getFirstName(),person.getLastName(),person.getSalary())上面的例子中我們已經看到collect方法是如何工作的。結合map方法,我們可以使用collect方法來將我們的結果集放到一個字符串,一個Set或一個TreeSet中:System.out.println("將PHPprogrammers的firstname拼接成字符串:");StringphpDevelopers=phpProgrammers.stream().map(Person::getFirstName).collect(joining(";"));//在進一步的操作中可以作為標記(token)System.out.println("將Javapro

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論