java8總結
- java8新特性總結
- 1. 行為參數化
- 2. lambda表達式
- 2.1 函數式接口
- 2.2 函數描述符
- 3. Stream API
- 3.1 付諸實踐
java8新特性總結
- 行為參數化
- lambda表達式
- Stream Api
1. 行為參數化
-
定義:行為參數化,就是一個方法接受多個不同的行為作為參數,并在內部使用它們,完成不同行為的能力。
-
行為參數化可讓代碼更好地適應不斷變化的要求,減輕未來的工作量。傳遞代碼,就是將新行為作為參數傳遞給方法。
-
方法引用
:在Java 8里寫下類::方法名
的時候,你就創建了一個方法引用,你同樣可以傳遞它。
package org.study.firstbase;import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;/*** Hello world!*/
public class AppFilter {public static void main(String[] args) {testPredicate();}public static void testPredicate() {List<Apple> apples = new ArrayList<Apple>();apples.add(new Apple("green", 140));apples.add(new Apple("green", 160));apples.add(new Apple("red", 140));apples.add(new Apple("red", 160));List<Apple> result = filterApples(apples, Apple::isGreenApple);for (Apple apple : result) {System.out.println(apple);}List<Apple> result2 = filterApples(apples, Apple::isHeavyApple);for (Apple apple : result2) {System.out.println(apple);}}static List<Apple> filterApples(List<Apple> inventory, Predicate<Apple> p) {List<Apple> result = new ArrayList<Apple>();for (Apple apple : inventory) {if (p.test(apple)) {result.add(apple);}}return result;}
}
2. lambda表達式
你可以在函數式接口
上使用Lambda表達式
2.1 函數式接口
2.2 函數描述符
函數式接口的抽象方法的簽名基本上就是Lambda表達式的簽名。我們將這種抽象方法叫作函數描述符
3. Stream API
- 流是“從支持數據處理操作的源生成的一系列元素”。
- 流操作有兩類:
中間操作
和終端操作
。 - 謂詞:一個返回 boolean的函數
- 總結
- Streams API可以表達復雜的數據處理查詢。常用的流操作總結在表5-1中。
- 你可以使用filter、distinct、skip和limit對流做篩選和切片。
- 你可以使用map和flatMap提取或轉換流中的元素。 ?你可以使用findFirst和findAny方法查找流中的元素。你可以用allMatch、noneMatch和anyMatch方法讓流匹配給定的謂詞。
- 這些方法都利用了短路:找到結果就立即停止計算;沒有必要處理整個流。
- 你可以利用reduce方法將流中所有的元素迭代合并成一個結果,例如求和或查找最大元素。
- filter和map等操作是無狀態的,它們并不存儲任何狀態。reduce等操作要存儲狀態才能計算出一個值。sorted和distinct等操作也要存儲狀態,因為它們需要把流中的所有元素緩存起來才能返回一個新的流。這種操作稱為有狀態操作。
- 流有三種基本的原始類型特化:IntStream、DoubleStream和LongStream。它們的操
作也有相應的特化。 - 流不僅可以從集合創建,也可從值、數組、文件以及iterate與generate等特定方法
創建。 - 無限流是沒有固定大小的流。
3.1 付諸實踐
在本節中,你會將迄今學到的關于流的知識付諸實踐。我們來看一個不同的領域:執行交易的交易員。你的經理讓你為八個查詢找到答案。你能做到嗎?我們在5.5.2節給出了答案,但你應 該自己先嘗試一下作為練習。
(1) 找出2011年發生的所有交易,并按交易額排序(從低到高)。 (2) 交易員都在哪些不同的城市工作過?
(3) 查找所有來自于劍橋的交易員,并按姓名排序。
(4) 返回所有交易員的姓名字符串,按字母順序排序。
(5) 有沒有交易員是在米蘭工作的?
(6) 打印生活在劍橋的交易員的所有交易額。 (7) 所有交易中,最高的交易額是多少?
(8) 找到交易額最小的交易。
package org.study.streamApi;import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;public class CaseTask {public static void main(String[] args) {Trader raoul = new Trader("Raoul", "Cambridge");Trader mario = new Trader("Mario","Milan");Trader alan = new Trader("Alan","Cambridge");Trader brian = new Trader("Brian","Cambridge");List<Transaction> transactions = Arrays.asList(new Transaction(brian, 2011, 300),new Transaction(raoul, 2012, 1000),new Transaction(raoul, 2011, 400),new Transaction(mario, 2012, 710),new Transaction(mario, 2012, 700),new Transaction(alan, 2012, 950));//(1) 找出2011年發生的所有交易,并按交易額排序(從低到高)。transactions.stream().filter(d -> d.getYear() == 2011).sorted(Comparator.comparing(Transaction::getValue)).forEach(System.out::println);//(2) 交易員都在哪些不同的城市工作過?transactions.stream().map(t -> t.getTrader().getCity()).distinct().forEach(System.out::println);//(3) 查找所有來自于劍橋的交易員,并按姓名排序。transactions.stream().map(t -> t.getTrader()).filter(t -> t.getCity().equals("Cambridge")).distinct().sorted(Comparator.comparing(Trader::getName)).forEach(System.out::println);//(4) 返回所有交易員的姓名字符串,按字母順序排序。transactions.stream().map(t -> t.getTrader().getName()).distinct().sorted((x, y) -> x.compareTo(y)).forEach(System.out::println);//(5) 有沒有交易員是在米蘭工作的?boolean milan = transactions.stream().anyMatch(t -> t.getTrader().getCity().equals("Milan"));System.out.println(milan);//(6) 打印生活在劍橋的交易員的所有交易額。transactions.stream().filter(t -> t.getTrader().getCity().equals("Cambridge")).map(Transaction::getValue).forEach(System.out::println);//(7) 所有交易中,最高的交易額是多少?Optional<Integer> maxValue = transactions.stream().map(Transaction::getValue).reduce(Integer::max);System.out.println(maxValue.get());//(8) 找到交易額最小的交易。Optional<Integer> minValue = transactions.stream().map(Transaction::getValue).reduce(Integer::min);System.out.println(minValue.get());}
}