Java Lamdba 学习
1. 前言
最近开放项目的时候总感觉许多时候代码冗余, 所以打算好好研究研究 lamdba 来让代码看起来更简介
2. 初探 Lambda
最经典的莫过于集合排序
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- public class Main {public static void main(String[] args) {
- List<Good> goods = new ArrayList<>();
- goods.add(new Good("Apple", 30));
- goods.add(new Good("Pear", 10));
- goods.add(new Good("Banana", 20));
- System.out.println("before sort");
- goods.forEach(g -> System.out.println(g));
- /**
- ** 通过 lambda 进行比较排序, 代替 Compator 的作用
- */
- Collections.sort(goods, (p1, p2) -> Integer.compare(p1.value, p2.value));
- System.out.println("after sort");
- goods.forEach(g -> System.out.println(g));
- }
- private static class Good {
- String name;
- int value;
- public Good(String name, int value) {
- this.name = name;
- this.value = value;
- }
- @Override
- public String toString() {
- return name + "->" + value;
- }
- }
- }
当 lambda 的参数为 1 个的时候可以省略小括号, 当 lambda 的函数体只有一条的时候也可以省略大括号
在编译器可以推断出类型的时候, 可以省略参数类型, 因为这的 compator 的参数类型只能是 Good, 所以 p1 和 p2 的数据类型一定为 Good, 故可以省略参数类型.
不仅在编写 compator 的时候可以采用 lambda 表达式, 例如 list 的 foreach 也可以使用 lambda 表达式, 例如打印列表的每一个元素.
3.Lambad 应用
首先定义一个筛选类
- private static class GoodFilter {
- public void printSomeGood(List<Good> goods, Predicate<Good> p) {
- /**
- * 列表的 foreach+java.util.function 的 Predicate 筛选
- */
- goods.forEach(g -> {
- if (p.test(g))
- System.out.println(g);
- });
- }
- }
进行筛选操作
- Predicate<Good> expensive = g -> g.value>= 20;
- Predicate<Good> cheap = g -> g.value <20;
- GoodFilter filter = new GoodFilter();
- System.out.println("Expensive Goods list");
- filter.printSomeGood(goods, expensive);
- System.out.println("Cheap Goods list");
- filter.printSomeGood(goods, cheap);
Predicate 为 java.util.function 包中函数, 该包下的其他函数请自行百度学习
与以前定义接口和接口实现的大量代码相比较, 无疑简洁很多.
4. Stream API 介绍
Stream 就如同一个迭代器 (Iterator), 单向, 不可往复, 数据只能遍历一次, 遍历过一次后即用尽了, 就好比流水从面前流过, 一去不复返. 而和迭代器又不同的是, Stream 可以并行化操作, 迭代器只能命令式地, 串行化操作.
- /**
- * 流式操作, 先筛选, 再将符合条件的元素转化为其 value 值, 最后相加打印
- */
- int sum = goods.stream()
- .filter(g -> g.value>= 20)
- .mapToInt(g -> g.value)
- .sum();
- System.out.println(sum);
- /**
- * 流式操作, 先筛选, 再将符合条件的商品转化为其姓名, 最后应用变为小写的操作, 最后通过 foreach 打印
- */
- List<String> ret = goods.stream()
- .filter(g -> g.value>= 20)
- .map(g -> g.name)
- .map(String::toLowerCase)
- .collect(Collectors.toList());
- ret.forEach(p->System.out.println(p));
要注意的是 goods 的元素并没有改变, 每次转换原有 Stream 对象不改变, 返回一个新的 Stream 对象 (可以有多次转换).
来源: http://www.bubuko.com/infodetail-2639972.html