java8 lambda常用方法汇总
在日常工作中,经常会用到 java8 的 lambda 新特性,可以让代码变得简洁,便于理解,并减少代码量,本文主要列举常用的 lambda 方法,主要涉及:forEach、collect、map、reduce、flatMap、peek、distinct、sorted、filter、allMatch、anyMatch、findFirst、Optional。
一、lambda demo
lambda示例代码如下:
package utils;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.google.common.collect.Lists.newArrayList;
/**
* java8 lambda常用方法汇总
*
* @Author: tinker
* @Date: 2022/02/09 17:21
*/
public class LambdaDemo {
public static void main(String[] args) {
// 1.forEach(替代for循环)
forEach();
// 2.collect(实现list中对象转换)
collect();
// 3.reduce
reduce();
// 4.map
map();
// 5.peek
peek();
// 6.distinct去重
distinct();
// 7.sorted排序(正序 -> Comparator.naturalOrder() 逆序 -> Comparator.reverseOrder())
sorted();
// 8.filter
filter();
// 9.allMatch(所有的都要满足)
allMatch();
// 10.anyMatch(所有的都要满足)
anyMatch();
// 11.findFirst
findFirst();
// 12.Optional
optional();
// 13.flatMap
flatMap();
}
public static void forEach() {
List<Integer> list1 = Arrays.asList(1, 2, 3);
// before
for (Integer val : list1) {
System.out.print(val + " ");
}
// after
list1.forEach(val -> System.out.print(val + " "));
System.out.println();
System.out.println();
}
public static void collect() {
// before
User user1 = new User(1L, "Tom");
User user2 = new User(2L, "Jack");
List<User> userList = Arrays.asList(user1, user2);
List<Person> personList1 = newArrayList();
for (User user : userList) {
Person person = new Person(user.getUserId(), user.getUserName());
personList1.add(person);
}
System.out.println(personList1.toString());
// after
List<Person> personList2 = userList.stream().map(LambdaDemo::user2Person).collect(Collectors.toList());
System.out.println(personList2.toString());
System.out.println();
}
@Data
@AllArgsConstructor
public static final class User {
User(Long userId, String userName) {
this.userId = userId;
this.userName = userName;
}
User(Long userId, String userName, String school) {
this.userId = userId;
this.userName = userName;
this.school = school;
}
private Long userId;
private String userName;
private int age;
private String school;
}
@Builder
@Data
@AllArgsConstructor
public static final class Person {
private Long personId;
private String personName;
}
public static Person user2Person(User user) {
return Person.builder()
.personId(user.getUserId())
.personName(user.getUserName())
.build();
}
public static void reduce() {
// 一个参数的reduce
reduce1();
// 两个参数的reduce
reduce2();
// 三个参数的reduce
reduce3();
}
/**
* 一个参数的reduce:将 list1 中的value相加
*/
public static void reduce1() {
List<Integer> list1 = Arrays.asList(1, 2, 3);
System.out.println("sum value should be 6, the reduce value is " + list1.stream().reduce((i, j) -> i + j).get());
}
/**
* 两个参数的reduce:将 result 与 list1 中的value相加
*/
public static void reduce2() {
List<Integer> list1 = Arrays.asList(1, 2, 3);
Integer result = 10;
System.out.println("sum value should be 16, the reduce value is " + list1.stream().reduce(result, (i, j) -> i + j));
}
/**
* 三个参数的reduce:将 identity 与 list1中的 value 相加, 之后再将结果相加
*/
public static void reduce3() {
List<Integer> list1 = Arrays.asList(1, 2, 3);
Integer identity = 1;
// (1 + 1) + (1 + 2) + (1 + 3) = 9
System.out.println("sum value should be 9, the reduce value is " +
list1.parallelStream().reduce(identity, (i, j) -> i + j, (i, j) -> i + j));
// (2 + 1) + (2 + 2) + (2 + 3) = 12
identity = 2;
System.out.println("sum value should be 12, the reduce value is " +
list1.parallelStream().reduce(identity, (i, j) -> i + j, (i, j) -> i + j));
System.out.println();
}
public static void map() {
List<String> list = Stream.of(
new User(1L, "Tom"),
new User(2L, "Jack"),
new User(3L, "Scott"))
.map(User::getUserName).collect(Collectors.toList());
System.out.println(list);
System.out.println();
}
/**
* peek 主要被用来debug, 不会该表元素的value, 当元素为对象, 实际结果会改变
*/
public static void peek() {
System.out.println(">> peek() method官方文档显示, 主要被用来debug, 打印流水线中的元素value");
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(e -> System.out.println("Filtered value: " + e))
.map(String::toUpperCase)
.peek(e -> System.out.println("Mapped value: " + e))
.collect(Collectors.toList());
System.out.println(">> peek 不会讲元素转换成大写格式");
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.peek(String::toUpperCase)
.forEach(e -> System.out.print(e + " "));
System.out.println();
System.out.println(">> map 对比");
Stream.of("one", "two", "three", "four")
.filter(e -> e.length() > 3)
.map(String::toUpperCase)
.forEach(e -> System.out.print(e + " "));
System.out.println();
System.out.println(">> 如果元素是对象, peek操作后, 实际的结果会改变");
List<User> userList = Stream.of(
new User(1L, ""),
new User(2L, ""),
new User(3L, ""))
.peek(u -> u.setUserName("scott"))
.collect(Collectors.toList());
System.out.println(userList);
System.out.println();
}
public static void distinct() {
List<Integer> list = Stream.of(1, 1, 1, 2, 2, 3).distinct().collect(Collectors.toList());
System.out.println(list);
System.out.println();
}
public static void sorted() {
// 正序
List<Integer> list1 = Stream.of(5, 3, 2, 4, 1)
.distinct()
.sorted(Comparator.naturalOrder())
// 也可以使用以下写法
// .sorted(((o1, o2) -> o1 - o2))
.collect(Collectors.toList());
System.out.println(list1);
// 逆序
List<Integer> list2 = Stream.of(5, 3, 2, 4, 1)
.distinct()
.sorted(Comparator.reverseOrder())
// 也可以使用以下写法
// .sorted(((o1, o2) -> o2 - o1))
.collect(Collectors.toList());
System.out.println(list2);
// 只针对特定字段进行排序
System.out.println(">> 针对 UserId进行排序, 写法一");
List<User> userList1 = Arrays.asList(
new User(3L, "Scott"),
new User(1L, "Tom"),
new User(2L, "Jack"));
userList1.sort((u1, u2) -> u1.userId.compareTo(u2.getUserId()));
System.out.println(userList1);
System.out.println(">> 针对 UserId进行排序, 写法二");
List<User> userList2 = Arrays.asList(
new User(3L, "Scott"),
new User(1L, "Tom"),
new User(2L, "Jack"));
// 错误示例:不会改变 userList2, 需要接收返回值
userList2.stream().sorted(Comparator.comparing(User::getUserId));
System.out.println(userList2);
System.out.println(">> Comparator 写法不会改变 userList2, 需要接收返回值才可以");
userList2 = Stream.of(
new User(3L, "Scott"),
new User(1L, "Tom"),
new User(2L, "Jack"))
.sorted(Comparator.comparing(User::getUserId))
// 逆序
// .sorted(Comparator.comparing(User::getUserId).reversed())
.collect(Collectors.toList());
System.out.println(userList2);
System.out.println(">> 多个字段排序");
userList2 = Stream.of(
new User(3L, "Scott", "北京大学"),
new User(1L, "Tom", "北京大学"),
new User(2L, "Jack", "清华大学"))
.sorted(Comparator.comparing(User::getSchool).thenComparing(User::getUserId))
.collect(Collectors.toList());
System.out.println(userList2);
System.out.println();
}
/**
* 过滤满足条件的元素
*/
public static void filter() {
List<Integer> list1 = Stream.of(5, 3, 2, 4, 1)
.filter(e -> e.compareTo(3) >= 0)
.sorted(Comparator.naturalOrder())
.collect(Collectors.toList());
System.out.println("Filtered list should be [3, 4, 5], list1 = " + list1);
System.out.println();
}
/**
* 所有的都要满足
*/
public static void allMatch() {
boolean result = Stream.of(
new User(3L, "Scott", 23, "北京大学"),
new User(1L, "Tom", 21, "北京大学"),
new User(2L, "Jack", 22, "清华大学"))
.allMatch(e -> e.getAge() >= 20);
System.out.println(result);
System.out.println();
}
/**
* 其中一个元素满足即可
*/
public static void anyMatch() {
boolean result = Stream.of(
new User(3L, "Scott", 18, "北京大学"),
new User(1L, "Tom", 21, "北京大学"),
new User(2L, "Jack", 17, "清华大学"))
.anyMatch(e -> e.getAge() >= 20);
System.out.println(result);
System.out.println();
}
/**
* 返回找到的第一个元素
*/
public static void findFirst() {
Optional<User> userOpt = Stream.of(
new User(3L, "Scott", 23, "北京大学"),
new User(1L, "Tom", 21, "北京大学"),
new User(2L, "Jack", 22, "清华大学"))
.filter(e -> e.getAge() >= 20)
.sorted(Comparator.comparing(User::getUserId))
.findFirst();
System.out.println(userOpt.get());
System.out.println();
}
/**
* 其中一个元素满足即可
*/
public static void optional() {
User user = null;
String userName = Optional.ofNullable(user).map(User::getUserName).orElse("default name");
System.out.println(userName);
user = new User(1L, "Tom", 21, "北京大学");
userName = Optional.ofNullable(user).map(User::getUserName).orElse("default name");
System.out.println(userName);
System.out.println();
}
/**
* 将二维列表转换为一维列表
*/
public static void flatMap() {
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(4, 5, 6);
List<Integer> list3 = Arrays.asList(7, 8);
List<List<Integer>> ll1 = newArrayList();
ll1.add(list1);
ll1.add(list2);
ll1.add(list3);
List<Integer> result = ll1.stream().flatMap(list -> list.stream())
.collect(Collectors.toList());
System.out.println(result);
System.out.println();
}
}