# lambda-code **Repository Path**: dj199209/lambda-code ## Basic Information - **Project Name**: lambda-code - **Description**: lambda学习笔记 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-09-05 - **Last Updated**: 2021-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Lambda表达式 ## 1. 基础语法 ### 1.0 基础 **Lambda 规定接口中只能有一个需要被实现的方法,不是规定接口中只能有一个方法。** - 其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ```java 基础语法: () -> {} ``` - `@FunctionalInterface` - 修饰函数式接口的,要求接口中的抽象方法只有一个。 这个注解往往会和 lambda 表达式一起出现。 ### 1.1 无返回有一个参数 - 接口 ```java /** * 无参数无返回值 */ @FunctionalInterface interface NoReturnNoParam { void method(); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现无参数无返回值 * 完整写法 */ NoReturnNoParam noReturnNoParam = () -> { System.out.println("ok"); }; noReturnNoParam.method(); System.out.println("==========分割线=========="); /* * 实现无参数无返回值 * 精简写法 */ NoReturnNoParam noReturnNoParam2 = () -> System.out.println("ok"); noReturnNoParam2.method(); System.out.println("==========分割线=========="); } ``` ### 1.2 无返回有一个参数 ```java /* * 有一个参数无返回值 */ @FunctionalInterface interface NoReturnOneParam { void method(int a); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现一个参数,无返回值 * 原始写法 */ NoReturnOneParam noReturnOneParam = (arg) -> { System.out.println(arg); }; noReturnOneParam.method(996); System.out.println("==========分割线=========="); /* * 实现一个参数,无返回值 * 精简写法 */ NoReturnOneParam noReturnOneParam2 = System.out::println; noReturnOneParam2.method(996); System.out.println("==========分割线=========="); } ``` ### 1.3 多个参数无返回值 - 接口 ```java /* * 多个参数无返回值 */ @FunctionalInterface interface NoReturnMoreParam { void method(int a, int b); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现多个参数,无返回值 * 原始写法 */ NoReturnMoreParam noReturnMoreParam = (a, c) -> { System.out.println(a + c); }; noReturnMoreParam.method(1, 2); System.out.println("==========分割线=========="); /* * 实现多个参数,无返回值 * 精简写法 */ NoReturnMoreParam noReturnMoreParam2 = (a, c) -> System.out.println(a + c); noReturnMoreParam2.method(1, 2); System.out.println("==========分割线=========="); } ``` ### 1.4 有返回值无参数 - 接口 ```java /* * 有返回值无参数 */ interface ReturnNoParam { int method(); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现无参数,有返回值 * 原始写法 */ ReturnNoParam returnNoParam = () -> { return 1; }; System.out.println("returnNoParam.method() = " + returnNoParam.method()); System.out.println("==========分割线=========="); /* * 实现无参数,有返回值 * 精简写法 */ ReturnNoParam returnNoParam2 = () -> 1; System.out.println("returnNoParam2.method() = " + returnNoParam2.method()); System.out.println("==========分割线=========="); } ``` ### 1.5 有返回值有一个参数 - 接口 ```java /* * 有返回值有一个参数 */ interface ReturnOneParam { int method(int a); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现一个参数,有返回值 * 原始写法 */ ReturnOneParam returnOneParam = (a) -> { return a; }; System.out.println("returnOneParam.method(1) = " + returnOneParam.method(1)); System.out.println("==========分割线=========="); /* * 实现一个参数,有返回值 * 精简写法 */ ReturnOneParam returnOneParam2 = (a) -> a; System.out.println("returnOneParam.method(1) = " + returnOneParam2.method(1)); System.out.println("==========分割线=========="); } ``` ### 1.6 有返回值有多个参数 - 接口 ```java /* * 有返回值有多个参数 */ interface ReturnMoreParam { String method(int a, int b); } ``` - 实现 ```java public static void main(String[] args) { /* * 实现多个参数,有返回值 * 原始写法 */ ReturnMoreParam returnMoreParam = (a, b) -> { return String.valueOf(a + b); }; System.out.println("returnMoreParam.method(5, 6) = " + returnMoreParam.method(5, 6)); /* * 实现多个参数,有返回值 * 精简写法 */ ReturnMoreParam returnMoreParam2 = (a, b) -> String.valueOf(a + b); System.out.println("returnMoreParam.method(5, 6) = " + returnMoreParam2.method(5, 6)); } ``` ## ## 2. 表达式引用方法 ### 2.1 一般方法 `方法归属者::方法名` 静态方法的归属者为类名,普通方法归属者为对象 ```java public class FuncLambda { public static void main(String[] args) { /* * 方法调用 */ ReturnNoParam returnNoParam = () -> { return num(); }; System.out.println("returnNoParam.method() = " + returnNoParam.method()); /* * 静态方法调用 * 原始写法 */ ReturnOneParam returnOneParam = (a) -> { return numOneParam(a); }; System.out.println("returnNoParam.method(a) = " + returnOneParam.method(1)); /* * 静态方法调用 * 精简写法 */ ReturnOneParam returnOneParam2 = FuncLambda::numOneParam; System.out.println("returnOneParam2 = " + returnOneParam2.method(2)); /* * 普通方法调用 * 精简写法 * 1. 必须new实例化一个对象 */ FuncLambda funcLambda = new FuncLambda(); ReturnOneParam returnOneParam1 = funcLambda::tow; System.out.println("returnOneParam1.method(9) = " + returnOneParam1.method(9)); } /* * 这是LambdaTest03里面的一个静态方法 * * @return */ public static int num() { return 10000; } /* * 这是LambdaTest03里面的一个静态方法 * * @return */ public static int numOneParam(int a) { return 10000 + a; } /* * 这是LambdaTest03里面的一个成员方法 */ public int tow(int a) { return a + 100000; } } ``` ### 2.2 构造方法创建对象 ```java @Data @NoArgsConstructor @AllArgsConstructor public class Item { int id; String name; double price; } ``` ```java public class ConstructLambda { public static void main(String[] args) { ItemCreatorBlankConstruct construct = () -> new Item(); Item item1 = construct.getItem(); System.out.println("item1 = " + item1); ItemCreatorBlankConstruct construct2 = Item::new; System.out.println("construct2.getItem() = " + construct2.getItem()); ItemCreatorParamContruct creatorParamContruct = (id, name, price) -> new Item(); Item item = creatorParamContruct.getItem(1, "2", 1.2); System.out.println(item); } } @FunctionalInterface interface ItemCreatorBlankConstruct { Item getItem(); } @FunctionalInterface interface ItemCreatorParamContruct { Item getItem(int id, String name, double price); } ``` ## 3. for循环 ### 3.1遍历简单集合 ```java public class ListForEachTest { /** * for循环合计 */ @Test public void ListForEach() { /* * 循环体 */ List intList = Arrays.asList(1, 2, 3, 4, 5); /* * 普通for循环 */ for (Integer integer : intList) { System.out.println(integer); } System.out.println("--------分割-------"); /* * lambda式for循环 */ intList.forEach(System.out::println); System.out.println("--------分割-------"); /* * 普通for循环,多语句 */ for (Integer integer1 : intList) { String s = integer1 + "\t"; System.out.print(s); } System.out.println("--------分割-------"); /* * lambda式for循环,多语句 */ intList.stream().map(integer1 -> integer1 + "\t").forEach(System.out::print); System.out.println("--------分割-------"); } } ``` ### 3.2 遍历复杂集合 ```java @Test public void ListForEach() { /* * 循环体,复杂循环 */ List itemList = new ArrayList<>(); itemList.add(new Item(11, "小牙刷", 12.05)); itemList.add(new Item(5, "日本马桶盖", 999.05)); itemList.add(new Item(7, "格力空调", 888.88)); itemList.add(new Item(17, "肥皂", 2.00)); itemList.add(new Item(9, "冰箱", 4200.00)); /* * 普通for循环 */ for (int i = 0; i < itemList.size(); i++) { System.out.println(itemList.get(i).getName()); } System.out.println("======分割======="); /* * 增强for循环 */ for (Item item : itemList) { System.out.println("item.getName() = " + item.getName()); } System.out.println("======分割======="); /* * lambda式for循环完整版 */ itemList.forEach(t -> { System.out.println("t.getName() = " + t.getName()); }); System.out.println("======分割======="); /** * lambda式for循环简写 */ itemList.forEach(t -> System.out.println(t.getName())); System.out.println("======分割======="); /* * lambda的for循环再次简写 */ itemList.forEach(System.out::println); } ``` ### 3.3 lambda移除 ```java public class ListRomoveLambdaTest { @Test public void ListSortTest() { /* * 循环体,复杂循环 */ List itemList = new ArrayList<>(); itemList.add(new Item(11, "小牙刷", 12.05)); itemList.add(new Item(5, "日本马桶盖", 999.05)); itemList.add(new Item(7, "格力空调", 888.88)); itemList.add(new Item(17, "肥皂", 2.00)); itemList.add(new Item(9, "冰箱", 4200.00)); System.out.println("======分割====="); itemList.forEach(System.out::println); System.out.println("======分割====="); /* * 常见方法 */ for (Item item : itemList) { if (item.getId() == 5) { itemList.remove(item); break; } } itemList.forEach(System.out::println); System.out.println("======分割====="); /* * lambda 方式 */ itemList.removeIf(t -> t.getId() == 17); itemList.forEach(System.out::println); System.out.println("======分割====="); } } ``` ### 3.4 lambda排序 ```java public class ListSortLambdaTest { @Test public void ListSortTest() { /* * 循环体,复杂循环 */ List itemList = new ArrayList<>(); itemList.add(new Item(11, "小牙刷", 12.05)); itemList.add(new Item(5, "日本马桶盖", 999.05)); itemList.add(new Item(7, "格力空调", 888.88)); itemList.add(new Item(17, "肥皂", 2.00)); itemList.add(new Item(9, "冰箱", 4200.00)); itemList.forEach(System.out::println); System.out.println("====分割===="); /* * 排序 */ Collections.sort(itemList, new Comparator() { @Override public int compare(Item o1, Item o2) { return (int) (o1.getPrice() - o2.getPrice()); } }); itemList.forEach(System.out::println); System.out.println("====分割===="); /* * lambda写法 */ Collections.sort(itemList, (o1, o2) -> { return (int) (o1.getPrice() - o2.getPrice()); }); /* * lambda简写 */ Collections.sort(itemList, (o1, o2) -> (int) (o1.getPrice() - o2.getPrice())); } } ``` ![image-20210822154815402](https://gitee.com/djaye/MyImage/raw/master/img/image-20210822154815402.png) ## 4. Stream方式 Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作,比如:筛选、排序、聚合等。 Stream可以由数组或集合创建,对流的操作分为两种: 1. 中间操作,每次返回一个新的流,可以有多个 2. 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。 3. stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果。 4. stream不会改变数据源,通常情况下会产生一个新的集合或一个值 stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行 ```java public class BaseStremm { @Test public void StreamTest() { /* * 基础操作 */ List itemList = new ArrayList<>(); itemList.add(new Item(11, "小牙刷", 12.05)); itemList.add(new Item(5, "日本马桶盖", 999.05)); itemList.add(new Item(7, "格力空调", 888.88)); itemList.add(new Item(17, "肥皂", 2.00)); itemList.add(new Item(9, "冰箱", 4200.00)); itemList.forEach(System.out::println); System.out.println("=====分割======="); /* * 老方法 */ ArrayList objects = new ArrayList<>(); for (Item item : itemList) { if (item.getId() == 11) { objects.add(item); } } objects.forEach(System.out::println); System.out.println("=====分割======="); /* * Stream处理方法 */ List collect = itemList.stream().filter(t -> t.getPrice() == 12.05).collect(Collectors.toList()); collect.forEach(System.out::println); } } ``` ### 4.1 Stream的创建 ```java public class CreatStream { @Test public void creatStream() { //1. Collection.stream()方法用集合创建 List list = Arrays.asList("1", "2", "3"); Stream stream = list.stream(); //2. Arrays.stream(T[] array) 方法用数组创建 Stream stream1 = list.stream(); //3. 使用Stream的静态方法:of()、iterate()、generate() //3.1 在99基础上每次加1,并取两个 Stream objectStream = Stream.of(1, 2, 3, "2", new Person()); Stream iterate = Stream.iterate(99, a -> a + 1).limit(2); //iterate.forEach(System.out::println); AtomicInteger integer = new AtomicInteger(10); Stream limit1 = Stream.generate(() -> integer.incrementAndGet()).limit(2); limit1.forEach(System.out::println); } ``` ### 4.2 遍历/匹配(`foreach`/`find`/`match`) #### 4.2.1 `foreach` ```java public class ForEachStream { @Test public void forEachStream() { List list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); List list2 = Arrays.asList(7, 6, 9, 3, 8, 2, 1); //1. 顺序遍历 list.stream().forEach(System.out::print); System.out.println(); System.out.println("=============="); //2. 并行遍历 list.parallelStream().forEach(System.out::print); } } ``` #### 4.2.2 find ```java public class FindStream { @Test public void findStream() { List list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); List list2 = Arrays.asList(7, 6, 9, 3, 8, 2, 1); // 遍历输出符合条件的元素 list.stream().filter(t -> t == 8).forEach(System.out::println); List collect = list.stream().filter(t -> t == 8).collect(Collectors.toList()); System.out.println("=========="); //遍历大于 6的元素 先找到大于6的元素 再组装成新的集合之后再遍历 list.stream().filter(t -> t > 6).forEach(System.out::println); List newList = list.stream().filter(t -> t > 6).collect(Collectors.toList()); newList.forEach(System.out::println); // 匹配第一个 Optional first = list.stream().findFirst(); Optional first1 = list.stream().filter(t -> t > 3).findFirst(); System.out.println("first1 = " + first1); System.out.println("first.getClass() = " + first.getClass()); // 匹配任意 适合于并行流(适用于并行流) 从大于6里面随机取一个 Optional any = list.stream().filter(t -> t > 6).findAny(); System.out.println("any = " + any.get()); } } ``` #### 4.2.3 match☆ ```java public class MatchStream { @Test public void matchStream() { List list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); List personList = new ArrayList(); personList.add(new Person("韩梅梅", 8900, 22, "女", "武汉")); personList.add(new Person("李磊", 7000, 33, "男", "上海")); personList.add(new Person("Lucy", 7800, 44, "女", "北京")); personList.add(new Person("狗哥", 8200, 55, "男", "深圳")); personList.add(new Person("Lily", 9500, 66, "女", "深圳")); personList.add(new Person("Jim", 7900, 77, "男", "深圳")); // 是否包含符合特定条件的元素 boolean b = list.stream().anyMatch(t -> t > 2); System.out.println("是否包含年龄为30岁 = " + personList.stream().anyMatch(t -> t.getAge() == 30)); } } ``` ### 4.3 filter筛选 ```java public class FilterStream { @Test public void filterStream() { List list = Arrays.asList(7, 6, 9, 3, 8, 2, 1); List personList = new ArrayList(); personList.add(new Person("韩梅梅", 8900, 22, "女", "武汉")); personList.add(new Person("李磊", 7000, 33, "男", "上海")); personList.add(new Person("Lucy", 7800, 44, "女", "北京")); personList.add(new Person("狗哥", 8200, 55, "男", "深圳")); personList.add(new Person("Lily", 9500, 66, "女", "深圳")); personList.add(new Person("Jim", 7900, 77, "男", "深圳")); //筛选出list大于6的 list.stream().filter(t -> t > 6).forEach(System.out::println); //筛选员工中工资高于8000的人,并形成新的集合 personList.stream().filter(t -> t.getSalary() > 8000).forEach(System.out::println); //返回新集合 List personNewList = personList.stream().filter(t -> t.getSalary() > 8000).collect(Collectors.toList()); System.out.println("personNewList = " + personNewList); //找出所有妹子 List personBySexList = personList.stream().filter(t -> t.getSex().equals("女")).collect(Collectors.toList()); System.out.println("personBySexList = " + personBySexList); //找出所有武汉的人 List personListByArea = personList.stream().filter(t -> t.getArea().equals("武汉")).collect(Collectors.toList()); System.out.println("personListByArea = " + personListByArea); //自行完成 处于天命的人 List personListByAge = personList.stream().filter(t -> t.getAge() > 50).collect(Collectors.toList()); System.out.println("personListByAge = " + personListByAge); } } ``` ### 4.4 聚合(max/min/count) ```java public class PolymericStream { @Test public void polymericStream() { //1 . 获取String集合中最长的元素 List list = Arrays.asList("李磊", "韩梅梅", "Lucy", "Jim"); //实现方法1-接口实现 Optional max = list.stream().max((t1, t2) -> t1.length() - t2.length()); System.out.println("max = " + max); //实现方法2(精简写法) Optional max1 = list.stream().max(Comparator.comparingInt(String::length)); System.out.println("max1 = " + max1); //2. 获取Integer集合中的最大值 List list2 = Arrays.asList(7, 6, 9, 4, 11, 6); Optional max3 = list2.stream().max(Integer::compareTo); System.out.println("max3 = " + max3); // 自然排序最大值 Integer max2 = list2.stream().max(Integer::compareTo).get(); System.out.println("max2 = " + max2); // 自定义排序用最大值方法取最小值 Integer minNum = list2.stream().max(new Comparator() { @Override public int compare(Integer o1, Integer o2) { return o2.compareTo(o1); } }).get(); System.out.println("maxNum = " + minNum); //找最小 Integer minInt = list2.stream().min(Integer::compareTo).get(); System.out.println("minInt = " + minInt); //普通计数 long count = list2.stream().count(); //记数 找出大于9的个元素个数 long count1 = list2.stream().filter(t -> t > 9).count(); System.out.println("count1 = " + count1); System.out.println("count = " + count); //3. 获取员工工资最高的人 List personList = new ArrayList(); personList.add(new Person("韩梅梅", 8900, 22, "女", "武汉")); personList.add(new Person("李磊", 7000, 33, "男", "上海")); personList.add(new Person("Lucy", 7800, 44, "女", "北京")); personList.add(new Person("狗哥", 8200, 55, "男", "深圳")); personList.add(new Person("Lily", 9500, 66, "女", "深圳")); personList.add(new Person("Jim", 7900, 77, "男", "深圳")); //接口方法 Person salaryPersonMax = personList.stream().max(new Comparator() { @Override public int compare(Person o1, Person o2) { return o1.getSalary() - o2.getSalary(); } }).get(); System.out.println("salaryPersonMax = " + salaryPersonMax); //简写 Optional salaryPersonMax2 = personList.stream().max(Comparator.comparingInt(Person::getSalary)); System.out.println("salaryPersonMax2 = " + salaryPersonMax2); //4 . 计算Integer集合中大于6的元素的个数 List list4 = Arrays.asList(7, 6, 4, 8, 2, 11, 9); long count2 = list4.stream().filter(t -> t > 8).count(); System.out.println("count2 = " + count2); } } ``` ### 4.5 映射(`map/flatMap`) #### 4.5.1`map` ```java public class MapTest { @Test public void mapTest() { //1. 英文字符串数组的元素全部改为大写。 String[] strArr = {"abcd", "bcdd", "defde", "fTr"}; List stringList = Arrays.asList(strArr); List collect = stringList.stream().map(t -> t.toUpperCase()).collect(Collectors.toList()); System.out.println("collect = " + collect); //整数数组每个元素+3 List intList = Arrays.asList(1, 3, 5, 7, 9, 11); List collect1 = intList.stream().map(t -> t + 3).collect(Collectors.toList()); System.out.println("collect1 = " + collect1); //2.4.5.3将员工的薪资全部增加1000 //3. 将员工的薪资全部增加1000 List personList = new ArrayList(); personList.add(new Person("韩梅梅", 8900, 18, "女", "武汉")); personList.add(new Person("李磊", 7000, 19, "男", "上海")); personList.add(new Person("Lucy", 7800, 17, "女", "北京")); personList.add(new Person("狗哥", 8200, 18, "男", "深圳")); personList.add(new Person("Lily", 9500, 17, "女", "深圳")); personList.add(new Person("Jim", 7900, 17, "男", "深圳")); //改变原来值的情况 List collect3 = personList.stream().map(t -> { t.setSalary(t.getSalary() + 1000); return t; }).collect(Collectors.toList()); List collect2 = personList.stream().map(t -> t.getSalary() + 1000).collect(Collectors.toList()); System.out.println("collect2 = " + collect2); System.out.println("collect3 = " + collect3); //不改变原有值的情况 List collect4 = personList.stream().map(t -> { Person person = new Person(); person.setSalary(t.getSalary() + 1000); person.setAge(t.getAge()); person.setArea(t.getArea()); person.setName(t.getName()); person.setSex(t.getSex()); return person; }).collect(Collectors.toList()); System.out.println("collect4 = " + collect4); } } ``` #### 4.5.2 `flatMap` ```java public class FlatMap { @Test public void flatMap() { ////将两个字符数组合并成一个新的字符数组。 List listStr2 = Arrays.asList("m-k-l-a", "1-3-5-7"); List collect = listStr2.stream().flatMap(t -> { String[] split = t.split("-"); return Arrays.stream(split); }).collect(Collectors.toList()); System.out.println("collect = " + collect); } } ``` ### 4.6 归约(reduce)