一 :那么Lambda有什么長處 :
1、操作簡單
2、代碼優化
錯誤謬誤 :
1、很是不易讀
二:Lambda表達式的尺度格局為 : ( 參數類型 參數名稱 ) -> { 代碼語句 }
三:Lambda的利用前提-函數式接口
3.1、利用Lambda必需具有接口,且要求接口中有且僅有一個抽象方式。無論是JDK內置的Runnable、Comparator接口仍是自界說的接口,只有當接口中的抽象方式存在且獨一時,才可以利用Lambda。
3.2、利用Lambda必需具有上下文揣度。也就是方式的參數或局部變量類型必需為Lambda對應的接口類型,才能利用Lambda作為該接口的實例。
初識lambda表達式:
package com.sgg.lambda;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import org.junit.Test;
public class TestLambda {
// 本來的匿名內部類
@Test
public void test1() {
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet<Integer> ts = new TreeSet<>(com);
}
// Lambda 表達式
@Test
public void test2() {
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
TreeSet<Integer> ts = new TreeSet<>(com);
}
List<Employee> employees = Arrays.asList(new Employee("張三", 12, 1200.99), new Employee("小明", 15, 4500.99),
new Employee("小麗", 16, 5500.99), new Employee("王二", 32, 1100.99), new Employee("二虎", 22, 9825.99),
new Employee("李靜", 18, 4502.99), new Employee("小三", 17, 1469.99));
// 需求獲取當前公司中員工春秋大于16的員工信息
public List<Employee> filterEmployees(List<Employee> employees) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (emp.getAge() > 16) {
emps.add(emp);
}
}
return emps;
}
// 需求獲取當前公司中員工工資大于5000的員工信息
public List<Employee> filterEmployees2(List<Employee> employees) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (emp.getSalary() > 5000) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test3() {
List<Employee> emps = filterEmployees2(employees);
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 優化體例一:利用設計模式-策略設計模式
public List<Employee> filterEmployee(List<Employee> employees, MyPredicate<Employee> mp) {
List<Employee> emps = new ArrayList<Employee>();
for (Employee emp : employees) {
if (mp.test(emp)) {
emps.add(emp);
}
}
return emps;
}
@Test
public void test4() {
// List<Employee> emps = filterEmployee(employees, new FilterEmployeeByAge());
List<Employee> emps = filterEmployee(employees, new FilterEmployeeBySalary());
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 優化體例二:匿名內部類
@Test
public void test5() {
List<Employee> emps = filterEmployee(employees, new MyPredicate<Employee>() {
@Override
public boolean test(Employee t) {
return t.getAge() < 16;
}
});
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 優化體例三:lambda表達式
@Test
public void test6() {
List<Employee> emps = filterEmployee(employees, (e) -> e.getAge() > 17);
for (Employee emp : emps) {
System.out.println(emp);
}
}
// 優化體例四:streamAPI
@Test
public void test7() {
employees.stream().filter((e) -> e.getAge() > 17).forEach(System.out::println);
employees.stream().map(Employee::getName).forEach(System.out::println);
}
}
Lambda表達式根本語法:
package com.sgg.lambda2;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import org.junit.Test;
/**
* 一 、Lambda 表達式的根本語法:java8中引入了一個新的操作符“->”改操作符稱為箭頭操作符或Lambda操作符
* 箭頭操作符將Lambda表達式拆分當作兩部門:
*
* 左側:Lambda的參數列表 右側:Lambda所需要執行的功能,即Lambda 體
*
* 語法格局一:無參數,無返回值 () -> System.out.println("hello lambda")
*
* 語法格局二:有一個參數,而且無返回值 (x) -> System.out.println(x)
*
* 語法格局三:有一個參數,而且無返回值,左側的參數小括號可以省略不寫。 x -> System.out.println(x)
*
* 語法格局四:有兩個個以上參數,有返回值,而且Lambda 體 中有多條語句。 Comparator<Integer> com = (x,y) -> {
* System.out.println("函數式接口, 成果測試!"); return Integer.compare(x, y); };
*
* 語法格局五:若Lambda 體 中只有一條語句,大括號和return都可以省略。 Comparator<Integer> com2 = (x,y) ->
* Integer.compare(x, y);
*
* 語法格局六:Lambda 表達式的參數列表的數據類型可以省略不寫,因為JVM編譯器可以經由過程上下文揣度出數據類型,即“類型揣度”
* 1、添加類型Comparator<Integer> com2 = (Integer x,Integer y) -> Integer.compare(x,
* y); 2、不寫類型Comparator<Integer> com2 = (x,y) -> Integer.compare(x, y);
*
*
* 上聯:擺布遇一括號省, 下聯:左側揣度類型省, 橫批:能省則省
*
* 二 、 Lambda表達式需要“函數式接口”的撐持
* 函數式接口:接口中只有一個抽象方式的接口,稱為函數式接口。可以利用注解 @FunctionalInterface潤色
*
* @FunctionalInterface:可以查抄是否是函數式接口
*
* @author Administrator
*
*/
public class TestLambda2 {
@Test
public void test1() {
int sum = 9;// jdk1.7 以前必需寫final jdk1.8之后可以省略
Runnable r1 = new Runnable() {
public void run() {
System.out.println("Hello world!" + sum);
}
};
r1.run();
System.out.println("-----------------------------------");
Runnable r2 = () -> System.out.println("hello lambda");
r2.run();
}
@Test
public void test2() {
Consumer<String> com = (x) -> System.out.println(x);
com.accept("我愛進修java!");
Consumer<String> con = x -> System.out.println(x);
con.accept("我愛進修java!");
}
@Test
public void test3() {
Comparator<Integer> com = (x, y) -> {
System.out.println("函數式接口, 成果測試!");
return Integer.compare(x, y);
};
com.compare(7, 8);
Comparator<Integer> com2 = (Integer x, Integer y) -> Integer.compare(x, y);
com2.compare(7, 8);
Comparator<Integer> com3 = (x, y) -> Integer.compare(x, y);
com3.compare(7, 8);
}
// 類型揣度演示,jdk1.7以前就有
@Test
public void test4() {
/*
* String[] sts ; sts = {"ssss","bbbbb"};
*/
String[] sts = { "ssss", "bbbbb" };
List<String> list = new ArrayList<>();
// jdk1.8 之后可以這樣寫
show(new HashMap<>());
}
public void show(Map<String, Object> map) {
}
// 需求對一個數進交運算
@Test
public void test5() {
Integer num = operation(5, x -> x * x);
System.out.println("5的平方:" + num);
}
public Integer operation(Integer num, MyFun fun) {
return fun.getValue(num);
}
}
Lambda表達式操練:
package com.sgg.lambda3;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import com.sgg.lambda1.Employee;
public class TestLambda3 {
List<Employee> employees = Arrays.asList(new Employee("張三", 12, 1200.99), new Employee("小明", 15, 4500.99),
new Employee("小麗", 16, 5500.99), new Employee("王二", 32, 1100.99), new Employee("二虎", 22, 9825.99),
new Employee("李靜", 18, 4502.99), new Employee("小三", 17, 1469.99));
// 操練1、挪用Collections.sort方式,經由過程心猿意馬制排序比力Employee(先按春秋巨細春秋不異按照姓名比力)
@Test
public void test1() {
Collections.sort(employees, (e1, e2) -> {
if (e1.getAge() == e2.getAge()) {
// return e1.getName().compareTo(e2.getName());
// 逆標的目的排序
return -e1.getName().compareTo(e2.getName());
} else {
// return Integer.compare(e1.getAge(),e2.getAge());
// 逆標的目的排序
return -Integer.compare(e1.getAge(), e2.getAge());
}
});
for (Employee emp : employees) {
System.out.println(emp);
}
}
// 操練2、
// 2.1 聲明函數式接口,接口中聲明抽象方式,public String getValue(String str);
// 2.2 聲明類TestLambda3,類中挪用方式利用接口作為參數,將一個字符串轉為大寫,并作為方式的返回值
// 2.3 將一個字符串的第下標位置2到4之間的字符串截取
@Test
public void test2() {
String trimStr = strHandler("\t\t\t我愛進修java", str -> str.trim());
System.out.println(trimStr);
String trimStr2 = strHandler("aaaaaaaaa", str -> str.toUpperCase());
System.out.println(trimStr2);
String trimStr3 = strHandler("我愛進修java", str -> str.substring(2, 4));
System.out.println(trimStr3);
}
public String strHandler(String str, MyFunction mf) {
return mf.getValue(str);
}
// 操練3
// 3.1聲明一個帶兩個泛型的函數式接口,泛型類型<T,R>,T為參數,R為返回值
// 3.2 接口中聲明對應的抽象方式
// 3.3 在TestLambda3類中聲明方式,利用接口作為參數,計較兩個long型參數的和。
// 3.4計較兩個long型參數的乘積
@Test
public void test3() {
long count = op(55, 20, (l1, l2) -> l1 + l2);
System.out.println(count);
long count2 = op(55, 20, (l1, l2) -> l1 * l2);
System.out.println(count2);
}
public long op(long l1, long l2, MyFunctionLong<Long, Long> ml) {
return ml.longCount(l1, l2);
}
}
內置函數式接口
package com.sgg.lambda4;
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;
import org.junit.Test;
/**
* jdk1.8 內置的四大焦點函數式接口
*
* Consumer<T>:消費型接口 void accept(T t);
*
* Supplier<T> :供給型接口 T get();
*
* Function<T, R> :函數型接口 R apply(T t);
*
* Predicate<T> : 斷言型接口 boolean test(T t);
*
*
* @author Administrator
*
*/
public class TestLambda4 {
// Consumer<T>:消費型接口
@Test
public void test1() {
happy(600, x -> System.out.println("小明喜好大保健每次消費:" + x));
}
public void happy(double money, Consumer<Double> con) {
con.accept(money);
}
// Supplier<T> :供給型接口
// 需求:發生必然的整數并放入調集中
@Test
public void test2() {
List<Integer> list = getNumList(10, () -> (int) (Math.random() * 100));
for (Integer integer : list) {
System.out.println(integer);
}
}
public List<Integer> getNumList(int num, Supplier<Integer> sup) {
List<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < num; i++) {
Integer n = sup.get();
list.add(n);
}
return list;
}
// Function<T, R> :函數型接口
// 用于字符串處置
@Test
public void test3() {
String str = strHandler("\t\t\t\t我愛java", x -> x.trim());
System.out.println(str);
String trimStr2 = strHandler("aaaaaaaaa", x -> x.toUpperCase());
System.out.println(trimStr2);
String trimStr3 = strHandler("我愛進修java", x -> x.substring(2, 4));
System.out.println(trimStr3);
}
public String strHandler(String str, Function<String, String> ft) {
return ft.apply(str);
}
// Predicate<T> : 斷言型接口
// 需求:將知足前提的字符串放入調集中去
@Test
public void test4() {
List<String> lists = Arrays.asList("sdsad", "我愛java", "我愛故國", "我愛人平易近");
List<String> listStr = filterStr(lists, x -> x.length() > 3);
for (String string : listStr) {
System.out.println(string);
}
}
public List<String> filterStr(List<String> listStr, Predicate<String> pre) {
List<String> lists = new ArrayList<>();
for (String str : listStr) {
if (pre.test(str)) {
lists.add(str);
}
}
return lists;
}
}
方式引用
package com.sgg.lambda5;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.junit.Test;
import com.sgg.lambda1.Employee;
/**
* 一 、方式引用:若Lambda體中內容有方式已經實現了,我們可以利用“方式引用” (可以理解為方式引用是Lambda表達式的另一種表示形式)
*
* 本家兒要有三種語法格局:
*
* 對象::實例方式名
*
* 類::靜態方式名
*
* 類::實例方式名
*
* 注重: Lambda體中挪用方式的參數列表與返回值類型,要與函數式接口中抽象方式的函數列表和返回值類型一致!
* 若Lambda參數列表中的第一參數是實例方式的挪用者,第二參數是實例方式的參數時,可以利用ClassName::method
*
* 二 、機關器引用
*
* 格局: ClassName::new
*
* 注重:需要挪用的機關器的參數列表要與函數式接口中抽象方式的參數列表連結一致!
*
* 三 、數組引用
*
* Type::new;
*
* @author Administrator
*
*/
public class TestMethodRef {
// 對象::實例方式名
@Test
public void test1() {
// 第一種
Consumer<String> con2 = (x) -> System.out.println(x);
// 第二種
PrintStream ps1 = System.out;
Consumer<String> con1 = (x) -> ps1.println(x);
// 第三種
PrintStream ps = System.out;
Consumer<String> con3 = ps::println;
con3.accept("我愛宿世界!");
}
@Test
public void test2() {
Employee emp = new Employee();
Supplier<String> su = () -> emp.getName();
String st = su.get();
System.out.println(st);
Employee emp2 = new Employee();
Supplier<Integer> su2 = () -> emp2.getAge();
Integer num = su2.get();
System.out.println(num);
}
// 類::靜態方式名
@Test
public void test3() {
Comparator<Integer> com1 = (x, y) -> Integer.compare(x, y);
Comparator<Integer> com2 = Integer::compare;
}
// 類::實例方式名
@Test
public void test4() {
BiPredicate<String, String> bp1 = (x, y) -> x.equals(y);
BiPredicate<String, String> bp2 = String::equals;
}
// 類::機關器引用
@Test
public void test5() {
Supplier<Employee> su1 = () -> new Employee();
Supplier<Employee> su2 = Employee::new;
Employee em = su2.get();
System.out.println(em);
}
@Test
public void test6() {
Function<String, Employee> fun = (x) -> new Employee(x);
Employee em = fun.apply("小麗");
System.out.println(em);
}
// 數組引用
@Test
public void test7() {
Function<Integer, String[]> fun1 = (x) -> new String[x];
String[] sts1 = fun1.apply(10);
System.out.println(sts1.length);
Function<Integer, String[]> fun2 = String[]::new;
String[] sts2 = fun2.apply(20);
System.out.println(sts2.length);
}
}
源碼地址:
鏈接: 1DpGycBWEJ43kXpuOgkzDQQ
提取碼: umxt
0 篇文章
如果覺得我的文章對您有用,請隨意打賞。你的支持將鼓勵我繼續創作!