深入淺出理解Java Lambda表達(dá)式之四大核心函數(shù)式的用法與范例
1.四大核心函數(shù)式接口
上一篇文章中說到了Lambda表達(dá)式中的基本語法,以及我們?nèi)绾巫远x函數(shù)式接口。但是在寫代碼的過程中,大家可能會發(fā)現(xiàn)一個(gè)問題:當(dāng)我們有一個(gè)新的需求時(shí),可以去自定義一個(gè)函數(shù)式接口,然后再創(chuàng)建一個(gè)它的實(shí)現(xiàn)類定義一些相關(guān)的業(yè)務(wù)邏輯行為。那么如果說我們有很多需求、這些需求可能還會不斷地變化,那么我們豈不是每次都要去創(chuàng)建新的實(shí)現(xiàn)類、同時(shí)再去修改之前創(chuàng)建好的實(shí)現(xiàn)類中的業(yè)務(wù)代碼?這可太麻煩了吧。。。
所以呢,Java8就為我們提供了四大核心函數(shù)式接口,使用起來非常的方便。

1.1 Consumer<T> : 消費(fèi)型接口
package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
*
*/
public class MyTest3 {
//Consumer<T> : 消費(fèi)型接口
@Test
public void test1() {
happy(6666.66,(m) -> System.out.println("本地雙11共消費(fèi) " + m + " 元?。?!"));
}
public void happy(double money, Consumer<Double> consumer) {
consumer.accept(money);
}
}

1.2 Supplier<T> : 供給型接口
package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
*
*/
public class MyTest3 {
//Supplier<T> : 供給型接口
@Test
public void test2() {
List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
for (Integer num : numList) {
System.out.println(num);
}
}
public List<Integer> getNumList(int num, Supplier<Integer> supplier) {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer n = supplier.get();
list.add(n);
}
return list;
}
}

1.3 Function<T, R> : 函數(shù)型接口
package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
*
*/
public class MyTest3 {
//Function<T, R> : 函數(shù)型接口
@Test
public void test3() {
String trimStr = strHandler("\t\t\t 張起靈-小哥 ", (str) -> str.trim());
System.out.println(trimStr);
String newStr = strHandler("我喜歡看盜墓筆記呀!?。?,(str) -> str.substring(4,8));
System.out.println(newStr);
}
public String strHandler(String str, Function<String,String> function) {
return function.apply(str);
}
}

1.4 Predicate<T> : 斷言型接口
package com.szh.java8;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/*
*
*/
public class MyTest3 {
//Predicate<T> : 斷言型接口
@Test
public void test4() {
List<String> list = Arrays.asList("Hello","張起靈-小哥","HashMap","jdk8","List","Set");
List<String> stringList = filterStr(list, (s) -> s.length() > 5);
for (String string : stringList) {
System.out.println(string);
}
}
public List<String> filterStr(List<String> strings, Predicate<String> predicate) {
List<String> strList = new ArrayList<>();
for (String str : strings) {
if (predicate.test(str)) {
strList.add(str);
}
}
return strList;
}
}

除此之外,還有一些其他的函數(shù)式接口,它們有一部分是上面提到的四大核心函數(shù)式接口的子接口。

2.方法引用
當(dāng)要傳遞給Lambda體的操作,已經(jīng)有實(shí)現(xiàn)的方法了,可以使用方法引用! 方法引用:使用操作符 “ :: ” 將方法名和對象或類的名字分隔開來。
如下三種主要使用情況 :
- 對象 :: 實(shí)例方法
- 類 :: 靜態(tài)方法
- 類 :: 實(shí)例方法
可以將方法引用理解為 Lambda 表達(dá)式的另外一種表現(xiàn)形式,方法引用所引用的方法的參數(shù)列表與返回值類型,需要與函數(shù)式接口中抽象方法的參數(shù)列表和返回值類型保持一致!
2.1 對象 :: 實(shí)例方法
@Test
public void test1() {
Consumer<String> con1 = (str) -> System.out.println(str);
con1.accept("Hello World!!!");
PrintStream ps = System.out;
Consumer<String> con2 = ps::println;
con2.accept("Hello Java8!!!");
Consumer<String> con3 = System.out::println;
con3.accept("Hello Lambda!!!");
}

@Test
public void test2() {
Employee emp = new Employee();
emp.setName("張起靈");
emp.setAge(18);
Supplier<? extends Object> sup1 = () -> emp.getName();
String str = (String) sup1.get();
System.out.println(str);
Supplier<Integer> sup2 = emp::getAge;
Integer age = sup2.get();
System.out.println(age);
}
package com.szh.java8;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Employee {
private Integer id;
private String name;
private Integer age;
private Double salary;
public Employee(Integer id) {
this.id = id;
}
public Employee(Integer id,String name) {
this.id = id;
this.name = name;
}
}

2.2 類 :: 靜態(tài)方法
@Test
public void test3() {
Comparator<Integer> com1 = (x,y) -> Integer.compare(x,y);
System.out.println(com1.compare(10, 20));
Comparator<Integer> com2 = Integer::compare;
System.out.println(com2.compare(300, 110));
}

2.3 類 :: 實(shí)例方法
若 Lambda 的參數(shù)列表的第一個(gè)參數(shù)是實(shí)例方法的調(diào)用者,第二個(gè)參數(shù)(或無參)是實(shí)例方法的參數(shù)時(shí),格式: ClassName::MethodName
@Test
public void test4() {
BiPredicate<String,String> bp1 = (str1,str2) -> str1.equals(str2);
System.out.println(bp1.test("Hello", "hello"));
BiPredicate<String,String> bp2 = String::equals;
System.out.println(bp2.test("Java", "Java"));
}

3.構(gòu)造器引用
格式 : ClassName::new
與函數(shù)式接口相結(jié)合,自動與函數(shù)式接口中方法兼容。構(gòu)造器的參數(shù)列表,需要與函數(shù)式接口中參數(shù)列表保持一致!
代碼中Employee類參考上面的案例。
@Test
public void test5() {
//無參構(gòu)造器
Supplier<Employee> sup1 = () -> new Employee();
System.out.println(sup1.get());
//無參構(gòu)造器
Supplier<Employee> sup2 = Employee::new;
System.out.println(sup2.get());
//一個(gè)參數(shù)構(gòu)造器
Function<Integer,Employee> function = Employee::new;
Employee employee = function.apply(1001);
System.out.println(employee);
//兩個(gè)參數(shù)構(gòu)造器
BiFunction<Integer,String,Employee> biFunction = Employee::new;
Employee emp = biFunction.apply(1001, "張起靈");
System.out.println(emp);
}

4.數(shù)組引用
格式 :類型[] :: new
@Test
public void test6() {
Function<Integer,String[]> fun = (x) -> new String[x];
String[] strings = fun.apply(10);
System.out.println(strings.length);
Function<Integer,String[]> fun2 = String[]::new;
String[] strArray = fun2.apply(50);
System.out.println(strArray.length);
}

以上就是深入淺出理解Java Lambda表達(dá)式之四大核心函數(shù)式的用法與范例的詳細(xì)內(nèi)容,更多關(guān)于Java Lambda表達(dá)式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java 實(shí)戰(zhàn)項(xiàng)目之在線點(diǎn)餐系統(tǒng)的實(shí)現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)在線點(diǎn)餐系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
IDEA中Java出現(xiàn)無效的源發(fā)行版錯誤的解決辦法
這篇文章主要給大家介紹了關(guān)于IDEA中Java出現(xiàn)無效的源發(fā)行版錯誤的解決辦法,IDEA中Java出現(xiàn)?效的源發(fā)?版解決辦法出現(xiàn)該問題的原因是項(xiàng)?Project當(dāng)中的jdk與電腦當(dāng)中的jdk版本不?致造成的,需要的朋友可以參考下2023-10-10
Mybatis-Plus實(shí)體類繼承Model的使用小結(jié)
Mybatis-Plus實(shí)體類繼承Model的使用是Mybatis-Plus中的一個(gè)重要特性,它允許開發(fā)者通過繼承Model類來快速實(shí)現(xiàn)一些通用的功能,本文主要介紹了Mybatis-Plus實(shí)體類繼承Model的使用小結(jié),感興趣的可以了解一下2024-07-07
SpringMVC結(jié)合ajaxfileupload.js實(shí)現(xiàn)文件無刷新上傳
這篇文章主要介紹了SpringMVC結(jié)合ajaxfileupload.js實(shí)現(xiàn)文件無刷新上傳,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10

