-
lambda 表達式的應用場景
-
Stream 的應用場景
-
Lambda/Stream 的進一步封裝
自定義函數式接口(用?jdk
?自帶的函數式接口也可以)
https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
import java.io.Serializable;/*** 可序列化的Functional** @author VampireAchao*/
@FunctionalInterface
public interface Func<T, R> extends Serializable {/*** 調用** @param t 參數* @return 返回值*/R apply(T t);
}/*** 可序列化的函數式接口實現類** @author VampireAchao*/
public class FuncImpl implements Func<Object, String> {/*** 調用** @param o 參數* @return 返回值*/@Overridepublic String apply(Object o) {return o.toString();}
}Func<String, Integer> func = new Func<String, Integer>() {/*** 調用** @param s 參數* @return 返回值*/@Overridepublic Integer apply(String s) {return s.hashCode();}};
Lambda
?這種簡寫的形式
java.util.stream (Java Platform SE 8 )
Func<String, String> func1 = (String s) -> {return s.toUpperCase();};Func<String, String> func2 = (String s) -> s.toUpperCase();
Func<String, String> func3 = s -> s.toUpperCase();
Func<String, String> func4 = String::toUpperCase;import java.util.function.Function;
import java.util.function.IntFunction;
import java.util.function.Supplier;/*** 語法糖——方法引用** @author VampireAchao*/
public class MethodReferences {public static Object staticSupplier() {return "whatever";}public Object instanceSupplier() {return "whatever";}public Object anonymousInstanceFunction() {return "whatever";}public static void main(String[] args) {// 引用構造函數Supplier<MethodReferences> conSup = () -> new MethodReferences();conSup = MethodReferences::new;// 數組構造函數引用IntFunction<int[]> intFunction = value -> new int[value];// intFunc == new int[20];int[] intFuncResult = intFunction.apply(20);// 引用靜態方法Supplier<Object> statSup = () -> staticSupplier();statSup = MethodReferences::staticSupplier;Object statSupResult = statSup.get();// 引用特定對象的實例方法Supplier<Object> instSup = new MethodReferences()::instanceSupplier;instSup = new MethodReferences()::instanceSupplier;Object instSupResult = instSup.get();// 引用特定類型的任意對象的實例方法Function<MethodReferences, Object> anonInstFunc = streamDemo -> streamDemo.anonymousInstanceFunction();anonInstFunc = MethodReferences::anonymousInstanceFunction;}}
jdk
?自帶的函數式接口寫法
import java.math.BigDecimal;
import java.util.function.*;/*** 常用的幾個函數式接口寫法** @author VampireAchao*/
class Usual {public static Consumer<Object> consumer() {// 有參數無返回值return o -> {};}public static Function<Integer, Object> function() {// 有參數有返回值return o -> o;}public static Predicate<Object> predicate() {// 有參數,返回值為booleanreturn o -> true;}public static Supplier<Object> supplier() {// 無參數有返回值return Object::new;}public static BiConsumer<String, Integer> biConsumer() {// 倆參數無返回值return (q, o) -> {};}public static BiFunction<Integer, Long, BigDecimal> biFunction() {// 倆參數,有返回值return (q, o) -> new BigDecimal(q).add(BigDecimal.valueOf(o));}public static UnaryOperator<Object> unaryOperator() {// 一個參數,返回值類型和參數一樣return q -> q;}public static BinaryOperator<Object> binaryOperator() {// 倆參數和返回值類型保持一致return (a, o) -> a;}}
Java 8 API
?的抽象稱為流?Stream
java.util.stream (Java Platform SE 8 )
// 聲明式編程是告訴計算機需要計算“什么”而不是“如何”去計算// 現在,我想要一個List,包含3個數字6List<Integer> sixSixSix =// 我想要:Stream// 數字6.generate(() -> 6)// 3個.limit(3)// 最后收集起來轉為List.collect(Collectors.toList());sixSixSix.forEach(System.out::print);//Stream 使用一種類似用 SQL 語句從數據庫查詢數據的直觀方式來提供一種對 Java 集合運算和表達的高階抽象。// 就像sql里的排序、截取// 我要把傳入的list逆序,然后從第五個(元素下標為4)開始取值,取4條abc = abc.stream()// 排序(按照自然順序的逆序).sorted(Comparator.reverseOrder())// 從下標為4開始取值.skip(4)// 取4條.limit(4)// 最后收集起來轉為List.collect(Collectors.toList());System.out.println("我要把傳入的list逆序,然后從第五個(元素下標為4)開始取值,取4條");abc.forEach(System.out::print);System.out.println();/*** 老辦法實現一個list,存儲3個6** @return [6, 6, 6]*/private static List<Integer> oldSix() {// 老辦法List<Integer> sixSixSix = new ArrayList<>(3);sixSixSix.add(6);sixSixSix.add(6);sixSixSix.add(6);System.out.println("老辦法實現一個list,存儲3個6");for (Integer integer : sixSixSix) {System.out.print(integer);}System.out.println();return sixSixSix;}/*** 新方法實現一個list,存儲3個6** @return [6, 6, 6]*/private static List<Integer> newSix() {List<Integer> sixSixSix = Stream.generate(() -> 6).limit(3).collect(Collectors.toList());System.out.println("新方法實現一個list,存儲3個6");sixSixSix.forEach(System.out::print);System.out.println();return sixSixSix;}// 管道中傳輸,節點中處理int pipe = abc.stream()// 篩選.filter(i -> i > 'G')// 排序.sorted(Comparator.reverseOrder()).mapToInt(Object::hashCode)// 聚合.sum();System.out.println("將26個字母組成的集合過濾出大于'G'的,逆序,再獲取hashCode值,進行求和");System.out.println(pipe);//元素流在管道中經過中間操作(intermediate operation)的處理,最后由最終操作 (terminal operation) 得到前面處理的結果。// 將26個大寫字母Character集合轉換為String然后轉換為小寫字符List<String> terminalOperation = abc.stream()// 中間操作(intermediate operation).map(String::valueOf).map(String::toLowerCase)// 最終操作(terminal operation).collect(Collectors.toList());System.out.println("26個大寫字母Character集合,轉換成String然后轉換為小寫字符,收集起來");terminalOperation.forEach(System.out::print);System.out.println();