在日常工作中,经常会用到 java8 的 lambda 新特性,可以让代码变得简洁,便于理解,并减少代码量,本文主要列举常用的 lambda 方法,主要涉及:forEach、collect、map、reduce、flatMap、peek、distinct、sorted、filter、allMatch、anyMatch、findFirst、Optional。
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(); } }