什么是lambda表达式
- JDK8开始支持lambda表达式,用来让程序编写更优雅
- 利用Lambda可以更简洁的实现匿名内部类与函数声明与调用
基于lambda提供stream流式处理极大简化对集合的操作
Lambda表达式语法格式
lambda operator ```java public interface MathOperation { public Float operate(Integer a, Integer b); } //(参数列表)->实现语句
public static void main(String[] args) { //1、标准使用方式 //约束条件:Lambda表达式只能实现有且只有一个抽象方法的接口,Java中成为函数式接口 MathOperation addition = (Integer a, Integer b) -> { System.out.println(“加法运算”); return a + b + 0f; }; System.out.println( addition.operate(5, 3)); //2、lambda允许忽略参数类型 MathOperation substraction = (a, b) -> { return Float.valueOf(a - b); }; System.out.println(substraction.operate(1111, (int) 11.1)); //3、单行实现代码可以省略大括号和return MathOperation multiplication = (a, b) -> Float.valueOf(a * b); System.out.println(multiplication.operate(3, 5)); }
- 使用逗号分隔参数,参数类型可以省略,单参数括号可以省略- 单行直接写,多行用{}包括,并且要在最后一句使用return返回结果- 函数式接口:有且只有一个抽象方法的接口称为函数式接口,可以使用Lambda表达式快速的实现函数式接口;函数式接口和Lambda表达式两者加起来形成了函数式编程<a name="YCQyi"></a>## 函数式编程- 函数式编程是基于函数式接口(有且只有一个抽象方法的接口称为函数式接口)并使用lambda表达的编程方式- 函数式编程理念是将代码作为可重用数据带入到程序运行中- 函数式编程强调“你想做什么”,而不是:“你想怎么做”- Java中拥有大量的函数式接口,如Java .lang.Runnable;JDK8后提供了一系列新的函数式接口,位于java.util.funcation- 函数式接口Predicate是新增的函数式接口,位于java.util.funcation;Predicate用于测试传入的数据是否满足判断要求;Predicate接口需要实现test()方法进行逻辑判断。```java/*** 理解函数式编程* Predicate函数式接口的使用方法*/public class PredicateSample {public static void main(String[] args) {Predicate<Integer> predicate = n -> n > 4;System.out.println(predicate.test(2));List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);//函数式编程理念是将代码作为可重用数据带入到程序运行中filter(list, n -> n % 2 == 1); //获取所有奇数filter(list, n -> n % 2 == 0);// 获取所有偶数filter(list, n -> n > 5 && n % 2 == 0);//获取所有大于5的偶数/* for (Integer integer : list) {if (!(integer % 2 == 0)) {System.out.println("integer = " + integer);}}*/}public static void filter(List<Integer> list, Predicate<Integer> predicate) {for (Integer integer : list) {if (predicate.test(integer)) {System.out.println("integer = " + integer);}}}}
| 接口 | 用途 |
|---|---|
| Cosumer |
对应有一个输入参数无输出的功能代码 |
| Function |
对应一个有输入参数且需要返回数据的功能带代码,第一个参数说明参数的类型,第二个参数说明返回值类型 |
| Predicate |
用于条件判断,固定返回布尔值 |
Consumer函数式接口
/*** Consumer接口的使用*/public class ConsumerSimple {public static void main(String[] args) {output(n -> System.out.println(n));output(s -> {System.out.println("向XXX网站发送数据包" + s);});}public static void output(Consumer<String> consumer) {String text = "天将降大任于斯人也,必先苦其心志,劳其筋骨,饿其体肤,空乏其身,行拂乱起所为";//consumer做什么并不清楚,只有在传入参数时才决定做什么consumer.accept(text);}}
Function函数式接口
/*** 利用Function函数式编程生成定长随机字符串*/public class FunctionSimple {public static void main(String[] args) {Function<Integer, String> randomStringFunction = l -> {String chars = "abcdefghigklmnopqrstuvwxyz0123456789";StringBuffer stringBuffer = new StringBuffer();Random random = new Random();for (int i = 0; i < l; i++) {int position = random.nextInt(chars.length());char c = chars.charAt(position);stringBuffer.append(c);}// return String.valueOf(stringBuffer);return stringBuffer.toString();};String s = randomStringFunction.apply(16);System.out.println("s = " + s);}}
函数式接口特殊检查注解:不满足函数式接口的要求就会报错
@FunctionalInterface //通知编译器这是函数式接口,进行抽象方法检查public interface MathOperation {public Float operate(Integer a, Integer b);}
Stream流式处理
Stream流式处理是建立在Lambda基础上的多数据处理技术
- Stream对集合数据处理进行高度抽象,极大简化代码量
- Stream可对集合进行迭代、去重、筛选、排序、聚合等一系列的操作
Stream常用方法 | 接口 | 用途 | | —- | —- | | forEach | 循环遍历 | | map | map方法用于映射每个元素到对应的结果 | | filter | filter方法用于通过设置的条件过滤出元素 | | limit | limit方法用于获取指定数量的流 | | sorted | sorted方法用于对流进行排序 | | Collectors | Collectors类实现将流转换成集合和聚合元素 |
Stream流的五种创建方式:后三种不常用,了解即可
// 基于数组进行创建@Testpublic void generator1() {String[] arr = {"Lily", "Andy", "Jackson", "Smith"};Stream<String> stream = Stream.of(arr);stream.forEach(s -> System.out.println(s));}//基于集合进行创建@Testpublic void generator2() {List<String> list = new ArrayList<>();list.add("Lily");list.add("Andy");list.add("Jackson");list.add("Smith");Stream<String> stream = list.stream();stream.forEach(s -> System.out.println(s));}//利用generator方法创建无限长度流@Testpublic void generator3() {Stream<Integer> stream = Stream.generate(() -> new Random().nextInt(100000));// stream.forEach(s -> System.out.println(s));stream.limit(10).forEach(s -> System.out.println(s));}//基于迭代器创建流;使用stream代替创痛的for循环;尽管如此使用较少@Testpublic void generator4() {Stream<Integer> stream = Stream.iterate(1, n -> n + 1);stream.limit(10).forEach(s -> System.out.println(s));}//基于字符序列创建流@Testpublic void generator5() {String string = "abcdefg我的";IntStream stream = string.chars();stream.forEach(c -> System.out.println((char) c));}
Stream常用方法
//提取集合中所有偶数并对其进行求和操作@Testpublic void case1() {List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6");Stream<String> stream = list.stream();//获取stream对象int sum = stream.mapToInt(s -> Integer.parseInt(s)) //mapToInt将流中每一个数据转换为整数.filter(n -> n % 2 == 0)// filter对流数据进行过滤.sum();// 求和System.out.println("sum = " + sum);}//所有名字首字母大写@Testpublic void case2() {List<String> list = Arrays.asList("lily", "smith", "jackson");List<String> newList = list.stream().map(s -> s.substring(0, 1).toUpperCase() + s.substring(1))//按指定的规则对每一个流数据进行转换,转换的结构仍然保存在当前的流中,无法对外进行输出// .forEach(s -> System.out.println("s = " + s));.collect(Collectors.toList());//collect 对流数据进行收集,生成新的List/Set(set会自动取出重复元素)System.out.println("newList = " + newList);}//将所有奇数从大到小进行排序,且不允许出现重复@Testpublic void case3() {List<Integer> list = Arrays.asList(2,3,2,44,33,67,23);List<Integer> newList = list.stream().distinct() //去除重复的流数据.filter(n -> n % 2 == 1).sorted((a, b) -> b - a) // 需要传入compare方法的实现,前一个参数代表前一个数据数据,.collect(Collectors.toList());System.out.println("newList = " + newList);}
