java compare 返回值_关于Java你不知道的那些事之Java8新特性[Lambda表达式和函数式接口]...
前言
為什么要用Lambda表達(dá)式?Lambda是一個(gè)匿名函數(shù),我們可以把Lambda表達(dá)式理解為是一段可以傳遞的代碼,將代碼像數(shù)據(jù)一樣傳遞,這樣可以寫(xiě)出更簡(jiǎn)潔、更靈活的代碼,作為一個(gè)更緊湊的代碼風(fēng)格,使Java語(yǔ)言表達(dá)能力得到了提升
實(shí)例代碼
Lambda表達(dá)式最先替代的就是匿名內(nèi)部類,假設(shè)原來(lái)我們寫(xiě)一個(gè)Comparator比較函數(shù),采用匿名內(nèi)部類的方式
/*** 原來(lái)使用匿名內(nèi)部類*/public static void test() {// 使用匿名內(nèi)部類,重寫(xiě)Intger的 compare方法Comparator<Integer> comparator = new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {return Integer.compare(o1, o2);}};// 傳入比較的方法TreeSet<Integer> ts = new TreeSet<>(comparator);}然后在采用Lambda表達(dá)式后
/*** 使用Lambda表達(dá)式解決匿名內(nèi)部類需要編寫(xiě)大量模板語(yǔ)言的問(wèn)題*/public static void test2() {Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);// 傳入比較的方法TreeSet<Integer> ts = new TreeSet<>(comparator);}策略設(shè)計(jì)模式
假設(shè)我們現(xiàn)在有一個(gè)需求,就是查找出員工里面年齡超過(guò)35的,我們使用策略設(shè)計(jì)模式
/*** 員工類** @author: 陌溪* @create: 2020-04-05-12:13*/ public class Employee {private String name;private int age;private double salary;// set get }然后創(chuàng)建一個(gè)接口,這里就是判定條件
/*** 接口* @param <T>*/ public interface MyPredicte<T> {public boolean test(T t); }我們實(shí)現(xiàn)這個(gè)接口
/*** 按年齡過(guò)濾** @author: 陌溪* @create: 2020-04-05-12:23*/ public class FilterEmployeeByAge implements MyPredicte<Employee> {@Overridepublic boolean test(Employee employee) {return employee.getAge() > 35;} }然后在具體的例子中使用
/*** 獲取當(dāng)前公司員工年齡大于35*/public static void test3() {List<Employee> employees = Arrays.asList(new Employee("張三", 18, 3333),new Employee("李四", 38, 55555),new Employee("王五", 50, 6666.66),new Employee("趙六", 16, 77777.77),new Employee("田七", 8, 8888.88));MyPredicte<Employee> mp = new FilterEmployeeByAge();List<Employee> emps = new ArrayList<>();for (Employee emp : emps) {if(mp.test(emp)) {emps.add(emp);}}}當(dāng)某一天需求變更了,變成需要查找金額大于60000的,那么只需要在編寫(xiě)一個(gè)實(shí)現(xiàn)類即可
/*** 按薪資過(guò)濾** @author: 輕狂書(shū)生FS* @create: 2020-10-05-12:23*/ public class FilterEmployeeBySalary implements MyPredicte<Employee> {@Overridepublic boolean test(Employee employee) {return employee.getSalary() > 60000;} }那么具體使用只需要更改為
/*** 獲取當(dāng)前公司薪資大于60000*/public static void test3() {List<Employee> employees = Arrays.asList(new Employee("張三", 18, 3333),new Employee("李四", 38, 55555),new Employee("王五", 50, 6666.66),new Employee("趙六", 16, 77777.77),new Employee("田七", 8, 8888.88));MyPredicte<Employee> mp = new FilterEmployeeBySalary();List<Employee> emps = new ArrayList<>();for (Employee emp : emps) {if(mp.test(emp)) {emps.add(emp);}}}這樣一個(gè)方法,被稱為策略設(shè)計(jì)模式
匿名內(nèi)部類
使用上面的策略設(shè)計(jì)模式,我們會(huì)發(fā)現(xiàn)一個(gè)問(wèn)題,就是每當(dāng)我需要增加一個(gè)條件的時(shí)候,就需要增加一個(gè)實(shí)現(xiàn)類,如果條件多了的話,那么就會(huì)有很多實(shí)現(xiàn)類,那么為了優(yōu)化,我們可以采取匿名內(nèi)部類的方式
/*** 優(yōu)化方式,采用匿名內(nèi)部類的方式*/public static void test5() {List<Employee> employees = Arrays.asList(new Employee("張三", 18, 3333),new Employee("李四", 38, 55555),new Employee("王五", 50, 6666.66),new Employee("趙六", 16, 77777.77),new Employee("田七", 8, 8888.88));// 匿名內(nèi)部類filterEmployee(employees, new MyPredicte<Employee>() {@Overridepublic boolean test(Employee employee) {return employee.getSalary() <= 5000;}});}直接在內(nèi)部類中,使用我們的過(guò)濾條件
Lambda表達(dá)式
/*** 使用Lambda表達(dá)式優(yōu)化*/public static void test6() {List<Employee> employees = Arrays.asList(new Employee("張三", 18, 3333),new Employee("李四", 38, 55555),new Employee("王五", 50, 6666.66),new Employee("趙六", 16, 77777.77),new Employee("田七", 8, 8888.88));List<Employee> list = filterEmployee(employees, (e) -> e.getSalary() <= 5000);list.forEach(System.out::println);}或者
/*** 不使用策略模式*/public static void test7() {List<Employee> employees = Arrays.asList(new Employee("張三", 18, 3333),new Employee("李四", 38, 55555),new Employee("王五", 50, 6666.66),new Employee("趙六", 16, 77777.77),new Employee("田七", 8, 8888.88));employees.stream().filter(e-> e.getSalary() >= 5000).limit(2).forEach(System.out::println);System.out.println("=========");employees.stream().map(Employee::getName).forEach(System.out::println);}學(xué)習(xí)Lambda
Lambda表達(dá)式基礎(chǔ)語(yǔ)法:Java8中引入了一個(gè)新的操作符 “->” 該操作符稱為箭頭操作符 或 Lambda操作符
箭頭操作符將Lambda表達(dá)式拆分為兩部分:
- 左側(cè):Lambda表達(dá)式的參數(shù)列表(可以想象成,是上面定義的接口中抽象方法參數(shù)的列表)
- 右側(cè):Lambda表達(dá)式中,所需要執(zhí)行的功能,即Lambda體(需要對(duì)抽象方法實(shí)現(xiàn)的功能)
語(yǔ)法格式
1、無(wú)參,無(wú)返回值
格式:
() -> System.out.println(“hello”);舉例:
public static void test() {Runnable r = new Runnable() {@Overridepublic void run() {System.out.println("hello");}};System.out.println("=========");Runnable runnable = () -> {System.out.println("hello lambda");};}JDK1.8以后,調(diào)用Lambda外的值,不需要增加final字段,它默認(rèn)已經(jīng)添加了final
int n = 10; Runnable runnable = () -> {System.out.println("hello lambda" + n); };2、有一個(gè)參數(shù),有返回值
格式:
(x) -> System.out.println(x); 或 (一個(gè)參數(shù)時(shí),小括號(hào)可以省略不寫(xiě)) x -> System.out.println(x);實(shí)例:
public static void test2() {Consumer<String> consumer = (x) -> System.out.println(x);consumer.accept("我在bilibili"); }3、有多個(gè)參數(shù),一個(gè)返回值
/*** 多個(gè)參數(shù),有返回值*/public static void test3() {Comparator<Integer> comparator = (x, y) -> {System.out.println("函數(shù)式接口");return Integer.compare(x, y);};}4、有多個(gè)參數(shù),只有一條語(yǔ)句
這個(gè)時(shí)候,可以省略大括號(hào) 和 return
/*** 多個(gè)參數(shù),函數(shù)體只有一條,并且有返回值時(shí)*/public static void test4() {Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);}類型推斷
Lambda中,表達(dá)式的參數(shù)列表的數(shù)據(jù)類型可以省略不寫(xiě),因?yàn)镴VM編譯器通過(guò)上下文推斷出,數(shù)據(jù)類型,即“類型推斷”。
(Integer x, Integer y) -> Integer.compare(x, y);但是底層的類型檢查還是有的,只是JDK底層幫我們做了類型檢查這件事
函數(shù)式接口
Lambda表達(dá)式需要“函數(shù)式接口”的支持
函數(shù)式接口:接口中只有一個(gè)抽象方法的接口,稱為函數(shù)式接口,如:
/*** 函數(shù)式接口 */ public interface MyPredicte<T> {public boolean test(T t); }可以使用注解 @FunctionalInterface 修飾的,則為函數(shù)式接口
/*** 接口,用于解決重復(fù)條件* @param <T>*/ @FunctionalInterface public interface MyPredicte<T> {public boolean test(T t); }場(chǎng)景
對(duì)一個(gè)數(shù)進(jìn)行某種運(yùn)算
首先創(chuàng)建一個(gè)函數(shù)式接口
@FunctionalInterface public interface MyFun {public Integer getValue(Integer value); }然后在定義一個(gè)方法,把方法作為參數(shù)傳遞
/*** 需求:對(duì)一個(gè)數(shù)進(jìn)行運(yùn)算*/public static void test5() {Integer value = operation(100, (x) -> x*x);System.out.println(value);}public static Integer operation(Integer num, MyFun myFun) {return myFun.getValue(num);}訓(xùn)練
- 調(diào)用Collections.sort()方法,通過(guò)定制排序比較兩個(gè)Employee(先比較年齡比,年齡相同比較姓名),使用Lambda表達(dá)式
Java內(nèi)置函數(shù)接口
Comsumer 消費(fèi)型接口
格式:Comsumer<T>
傳入?yún)?shù),然后對(duì)參數(shù)進(jìn)行操作,沒(méi)有返回值
/*** 消費(fèi)型接口*/public static void test() {happy(1000, (m) -> System.out.println("消費(fèi)成功:" + m + "元"));}public static void happy(double money, Consumer<Double> consumer) {consumer.accept(money);}Supplier 供給型接口
格式:Supplier<T>
T get();
傳入?yún)?shù),對(duì)參數(shù)進(jìn)行操作,然后有返回值
/*** 供給型接口,供給功能如何實(shí)現(xiàn)*/public static void test2() {List<Integer> list = getNumList(10, () -> {Integer a = (int)(Math.random() * 10);return a;});list.stream().forEach(System.out::println);}/*** 產(chǎn)生指定個(gè)數(shù)的整數(shù)* @param n* @return*/public static List<Integer> getNumList(Integer n, Supplier<Integer> supplier) {List<Integer> list = new ArrayList<>();for (int i = 0; i < n; i++) {list.add(supplier.get());}return list;}最后輸出結(jié)果
0 5 9 4 4 3 4 5 0 3Function 函數(shù)型接口
格式:Function<T,R>
R apply(T t);
/*** 函數(shù)型接口* Function<T, R>*/public static void test3() {String str = strHandler("abcdefg", (x) -> {return x.toUpperCase().substring(0, 5);});System.out.println(str);}/*** 需求:用于處理字符串*/public static String strHandler(String str, Function<String, String> function) {// 使用apply方法進(jìn)行處理,怎么處理需要具體實(shí)現(xiàn)return function.apply(str);}輸出結(jié)果:
ABCDEPredicate 斷言型接口
格式:Predicate<T>, 用于做一些判斷
/*** 斷言型接口(把長(zhǎng)度大于3的str過(guò)濾出來(lái))*/public static void test4() {List<String> list = Arrays.asList("abc", "abcd", "df", "cgg", "aaab");List<String> result = strPredict(list, (x) -> x.length() > 3);result.forEach(item -> {System.out.println(item);});}/*** 將滿足條件的字符串,放入到集合中*/public static List<String> strPredict(List<String> list, Predicate<String> predicate) {List<String> result = new ArrayList<>();list.forEach(item -> {if(predicate.test(item)) {result.add(item);}});return result;}擴(kuò)展
上述的四大核心接口,并不能被適用于一個(gè)特殊的應(yīng)用場(chǎng)景,只能滿足大部分的需求
因?yàn)樗麄儗?duì)于參數(shù)的參入有局限性
同時(shí)后面針對(duì)這樣的情況,后面也使用子接口,進(jìn)行了解決
作者:輕狂書(shū)生FS原文鏈接:https://blog.csdn.net/LookForDream_/article/details/109157130
總結(jié)
以上是生活随笔為你收集整理的java compare 返回值_关于Java你不知道的那些事之Java8新特性[Lambda表达式和函数式接口]...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 普通平键的主要尺寸有_工字钢尺寸大全
- 下一篇: 25 linux ndk 头文件_正点原