Lambda
Lambda有四个重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。
函数式编程
接口只能有一个方法时,才能使用函数式编程(Lambda表达式)。
任何借口,如果只包含唯一一个抽象方法,那么它就是一个函数式接口。函数式接口,我们可以通过lambda表达式来创建该接口的对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class LambdaTest { public static void main(String[] args) { MathOperation increase = (int a, int b) -> a + b; MathOperation substraction = (a, b) -> a - b; SayMessage sayMessage = s -> System.out.println(s); Test test = () -> { System.out.println("Test.test()"); }; int result1 = increase.operation(10, 20); int result2 = substraction.operation(10, 20); System.out.println("result1 : " + result1); System.out.println("result2 : " + result2); sayMessage.print("SayMessage.print()"); test.test(); } interface MathOperation{ int operation(int a, int b); } interface SayMessage{ void print(String s); } interface Test{ void test(); } }
|
结果如下图所示:
Lambda引用外部局部变量
- Lambda可以引用外部的局部变量;
- Lambda不能修改外部局部变量的值;
- Lambda不能声明一个与局部变量同名的参数或者局部变量。
Lambda表达式
peek, map, filter, sorted, grouping
peek
修改对象中属性值
1 2 3 4 5 6 7 8 9 10 11
| public static void lambdaPeek() { System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users2 = users.stream() .peek(u -> u.setDescription(RandomUtil.randomString(20))) .peek(u -> u.setAge(u.getAge() + 100)) .collect(Collectors.toList()); users2.forEach(System.out::println); }
|
map
取出对象的某个属性,转换为新的集合
1 2 3 4 5 6 7 8 9 10
| public static void lambdaMap() { System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<Long> usersId = users.stream().map(User::getUserId).collect(Collectors.toList()); usersId.forEach(System.out::println); String names = users.stream().map(User::getName).collect(Collectors.joining(", ")); System.out.println("names = " + names); }
|
filter
过滤,筛选出需要的数据
1 2 3 4 5 6 7 8
| public static void lambdaFilter() { System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users2 = users.stream().filter(user -> user.getGender() == 1).collect(Collectors.toList()); users2.forEach(System.out::println); }
|
sorted
排序
1 2 3 4 5 6 7 8
| public static void lambdaSorted() { System.out.println("lambdaSorted---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaSorted---------------------------------------------------------------------------------------------------------------------"); List<User> users2 = users.stream().sorted((x, y) -> y.getAge() - x.getAge()).collect(Collectors.toList()); users2.forEach(System.out::println); }
|
match
anyMatch:只要有一个元素匹配传入的条件,就返回 true。
allMatch:只有有一个元素不匹配传入的条件,就返回 false;如果全部匹配,则返回 true。
noneMatch:只要有一个元素匹配传入的条件,就返回 false;如果全部不匹配,则返回 true。
1 2 3 4 5 6 7 8 9 10
| public static void lambdaMatch() { System.out.println("---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("---------------------------------------------------------------------------------------------------------------------"); boolean anyMatch = users.stream().anyMatch(user -> user.getGender() == 1); boolean allMatch = users.stream().allMatch(user -> user.getGender() == 1); boolean noneMatch = users.stream().noneMatch(user -> user.getGender() == 1); System.out.println("anyMatch = " + anyMatch + ", allMatch = " + allMatch + ", noneMatch = " + noneMatch); }
|
reduce
计算数字类型
1 2 3 4 5 6 7 8 9 10
| public static void lambdaReduce() { System.out.println("lambdaReduce---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaReduce---------------------------------------------------------------------------------------------------------------------"); Integer sum1 = users.stream().map(User::getAge).reduce(Integer::sum).orElse(0); Integer sum2 = users.stream().map(User::getAge).reduce(10, Integer::sum); Integer result = users.stream().map(User::getAge).reduce((a, b) -> - a - b).orElse(0); System.out.println("sum1 = " + sum1 + ", sum2 = " + sum2 + ", result = " + result); }
|
summaryStatistics
mapToInt, mapToLong, mapToDouble 返回值为IntStream, LongStream, DoubleStream
IntSummaryStatistics, LongSummaryStatistics, DoubleSummaryStatistics这些对象均包含:
4个属性:min, max, sum, count;
5个方法:getMin(), getMax(), getSum(), getCount(), getAverage()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static void lambdaSummaryStatistics() { System.out.println("lambdaMapToInt---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaMapToInt---------------------------------------------------------------------------------------------------------------------"); IntSummaryStatistics stats = users.stream().sorted(Comparator.comparingInt(User::getAge)) .limit(5).mapToInt(User::getAge).summaryStatistics(); IntSummaryStatistics stats1 = users.stream().sorted(Comparator.comparingInt(User::getAge)) .limit(5).collect(Collectors.summarizingInt(User::getAge)); long sum = stats.getSum(); double average = stats.getAverage(); long count = stats.getCount(); int max = stats.getMax(); int min = stats.getMin(); System.out.println("lambdaMapToInt1: sum = " + sum + ", average = " + average + ", count = " + count + ", max = " + max + ", min = " + min); long sum1 = stats1.getSum(); double average1 = stats1.getAverage(); long count1 = stats1.getCount(); int max1 = stats1.getMax(); int min1 = stats1.getMin(); System.out.println("lambdaMapToInt2: sum = " + sum1 + ", average = " + average1 + ", count = " + count1 + ", max = " + max1 + ", min = " + min1); }
|
Collectors
转换集合类型的方法:
toList, toMap, toSet
分组:
groupBy, partitioningBy
静态方法:
- 计数: count
- 平均值: averagingInt、 averagingLong、 averagingDouble
- 最值: maxBy、 minBy
- 求和: summingInt、 summingLong、 summingDouble
- 统计以上所有: summarizingInt、 summarizingLong、 summarizingDouble
toMap
key不能重复,重复是会抛出异常:java.lang.IllegalStateException: Duplicate key ...
1 2 3 4 5 6 7 8
| public static void lambdaToMap() { System.out.println("lambdaToMap---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaToMap---------------------------------------------------------------------------------------------------------------------"); Map<Long, User> userMap = users.stream().collect(Collectors.toMap(User::getUserId, u -> u)); System.out.println(JSONUtil.toJsonStr(userMap)); }
|
groupBy
1 2 3 4 5 6 7 8
| public static void lambdaGroup() { System.out.println("lambdaGroup---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaGroup---------------------------------------------------------------------------------------------------------------------"); Map<Integer, List<User>> userMap = users.stream().collect(Collectors.groupingBy(User::getAge)); System.out.println(JSONUtil.toJsonStr(userMap)); }
|
partitionBy
1 2 3 4 5 6 7 8
| public static void lambdaPartition() { System.out.println("lambdaPartition---------------------------------------------------------------------------------------------------------------------"); List<User> users = User.getUsers(); users.forEach(System.out::println); System.out.println("lambdaPartition---------------------------------------------------------------------------------------------------------------------"); Map<Boolean, List<User>> userMap = users.stream().collect(Collectors.partitioningBy(u -> u.getAge() >= 25)); System.out.println(JSONUtil.toJsonStr(userMap)); }
|