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());}
}