【Java】Java Lambda

img-cover

Lambda

Lambda有四个重要特征:

  1. 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
  2. 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
  3. 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
  4. 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

函数式编程

接口只能有一个方法时,才能使用函数式编程(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();
}
}

结果如下图所示:

Lambda01

Lambda引用外部局部变量

  1. Lambda可以引用外部的局部变量;
  2. Lambda不能修改外部局部变量的值;
  3. 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

静态方法:

  1. 计数: count
  2. 平均值: averagingInt、 averagingLong、 averagingDouble
  3. 最值: maxBy、 minBy
  4. 求和: summingInt、 summingLong、 summingDouble
  5. 统计以上所有: 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));
}
-------------本文结束感谢您的阅读-------------