一、Lambda表达式
1.1 什么是Lambda表达式?
Lambda表达式是JDK8中一个语法糖。他可以对某些匿名内部类的写法进行简化。它是函数式编程思想的一个重要体现。让我们不用关注是什么对象。而是更关注我们对数据进行了什么操作。
Lambda表达式主要运用在将匿名内部类代码进行优化,当接口中只有且只有一个抽象方法的时候,我们可以将这个方法使用Lambda表达式进行优化
基本语法:
(参数列表)->{代码体}
1.2 省略规则
- 参数类型可以省略
- 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略
- 方法只有一个参数时小括号可以省略(方法没有参数时必须加上小括号)
- 以上这些规则都记不住也可以省略不记
1.3 练习
1.3.1 创建线程时
```java // 原始写法: new Thread(new Runnable(){ @Override public void run() {
} }).start();System.out.println("Hello World");
//Lambda表达式 new Thread(() -> System.out.println(“Hello World”)).start();
<a name="glChi"></a>### 1.3.2 IntBinaryOperator类```javapublic static int calculateNum(IntBinaryOperator operator){int a = 10;int b = 20;return operator.applyAsInt(a, b);}// 原始写法public static void main(String[] args) {int i = calculateNum(new IntBinaryOperator(){@Overridepublic int applyAsInt(int left,int right){return left + right;}});System.out.println("i = " + i);}//Lambda表达式public static void main(String[] args) {int i = calculateNum((int left, int right) -> {return left + right;});System.out.println("i = " + i);}
二、Stream流式编程
2.1 概念
Java8的Stream使用的是函数式编程模式,如同它的名字一样,它可以被用来对集合或数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。
我们可以将数组或集合转换成流来进行操作,每个流都必须要有终结操作才能被执行
2.2 创建流
2.2.1 单列集合
List<Author> authors = getAuthors();Stream<Author> stream = authors.stream();
2.2.2 数组
Integer[] arr = {1,2,3,4,5};Stream<Integer> stream = Arrays.stream(arr);Stream<Integer> stream2 = Stream.of(arr);
2.2.3 双列集合
Map<String,Integer> map = new HashMap<>();map.put("蜡笔小新",19);map.put("黑子",17);map.put("日向翔阳",16);Stream<Map.Entry<String, Integer>> stream = map.entrySet().stream();
2.3 流的中间操作
2.3.1 filter方法
可以对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中。
// 例如:打印集合中姓名长度大于1的作者名字List<Author> authors = getAuthors();authors.stream().filter(author -> author.getName().length() > 1).forEach(author -> System.out.println(author.getName()));//实际上,是去调用内部的test方法,我们通过匿名内部类的形式可以看出authors.stream().filter(new Predicate<Author>() {@Overridepublic boolean test(Author author) {return author.getName().length() > 1;}}).forEach(item -> System.out.println(item.getName()));
2.3.2 map方法
可以把对流中的元素进行计算或转换。实际上是调用了内部的apply()方法,通过给Function接口指定泛型,就可以将我们流中原来的元素类型,转换成指定类型。后续操作的就是该类型了。
List<Author> authors = getAuthors();authors.stream().map(new Function<Author, String>() {@Overridepublic String apply(Author author) {return author.getName();}}).forEach(item -> System.out.println(item));
通过Stream Trace工具可以直观的感受到
我们也可以对流中的元素进行计算,例如:我们需要将集合中所有作者的年龄 + 10
List<Author> authors = getAuthors();authors.stream().map( author -> author.getAge()).map( age -> age + 10).forEach( item -> System.out.println(item));
2.3.3 distinct方法
可以去除流中的重复元素。distinct方法是依赖Object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。
注意: 如果我们使用了
Lombok插件,那么我们可以直接通过@Data注解来帮我们生成equals方法
List<Author> authors = getAuthors();authors.stream().distinct().forEach(item -> System.out.println(item.getName()));
2.3.4 sorted方法
可以对流中的元素进行排序。
List<Author> authors = getAuthors();authors.stream().distinct().sorted().forEach(author -> System.out.println(author.getAge()));
注意: 该方法会返回由该流的元素组成的流,按自然顺序排序。如果该流的元素不是
Comparable,则在执行终端操作时可能会抛出java.lang.ClassCastException, 所以我们需要在实体类对象中实现Comparable接口,并重写compareTo()方法
我们也可以使用这个带有参数的sorted()方法,重写一个compare()方法即可。
List<Author> authors = getAuthors();authors.stream().distinct().sorted(((o1, o2) -> o2.getAge() - o1.getAge())).forEach(author -> System.out.println(author.getAge()));
2.3.5 limit方法
可以设置流的最大长度,超出的部分将被抛弃。
List<Author> authors = getAuthors();authors.stream().limit(2).forEach(author -> System.out.println(author));
2.3.6 skip方法
跳过流中的前n个元素,返回剩下的元素
List<Author> authors = getAuthors();authors.stream().skip(2).forEach(author -> System.out.println(author));
2.3.7 flatMap方法
map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。
List<Author> authors = getAuthors();authors.stream().flatMap(author -> author.getBooks().stream()).distinct().forEach(author -> System.out.println(author.getName()));

