教你会用Lambda和Stream流

编程入门 行业动态 更新时间:2024-10-08 20:30:39

<a href=https://www.elefans.com/category/jswz/34/1768925.html style=教你会用Lambda和Stream流"/>

教你会用Lambda和Stream流

文章目录

  • Lambda和Stream流
    • 一、Lambda表达式
      • 1、函数式接口
      • 2.Lambda表达式
        • 2.1基本格式
        • 2.2 Lambda演示
          • 2.2.1有参数有返回值Lambda
          • 2.2.2 有参数无返回值Lambda
          • 2.2.3无参数有返回值Lambda
          • 2.2.4无参数无返回值Lambda
    • 二、Stream流
      • 1.概述
      • 2.Stream流相关方法
      • 3.相关代码演示

Lambda和Stream流

一、Lambda表达式

1、函数式接口

介绍Lambda之前,首先介绍一下函数式接口,函数式接口是Lambda和方法引用使用的前提。

格式:

@FunctionalInterface
interface 接口名 {void 方法名();
}

值得注意的是:

1.函数式接口中只可以定义一个缺省属性是 public abstract 的尚未实现的方法。

	2.	Lambda表达式只在JDK1.8及以上版本可以使用3.	@FunctionalInterface为开启函数式接口严格检查,如果定义错误,编译器立马就会报错,但是如果本身就是函数式接口,那么不写也仍然是函数式接口。

2.Lambda表达式

2.1基本格式

对于Lambda表达式我们只需要关注函数式接口中未实现方法的参数和返回值。

基本格式:

() -> {}() 中是联想的参数临时变量
-> 固定格式
{} 执行任务的代码块
2.2 Lambda演示

根据返回值和参数的不同,又可以将Lamdba分为四种

有参数有返回值

有参数无返回值

无参数有返回值

无参数无返回值

JDK1.8自带很多函数式接口,接下来用那些来举例。

2.2.1有参数有返回值Lambda

​ 有参数有返回值的接口在开发中很常用,并且泛型也使得接口的使用更加自由,随心所欲,接下来用类型转换函数式接口来进行代码演示。

过滤器接口,判断接口,条件接口

@FunctionalInterface
public interface Predicate<T> {/*** 过滤器接口约束的方法,方法参数是用户使用时约束泛型对应具体数据参数* 返回值类型是 boolean 类型,用于条件判断,数据过来** @param t 用户约束泛型对应的具体数据类型参数* @return boolean 数据,判断结果反馈*/boolean test(T t);
}

比较器接口

@FunctionalInterface
interface Comparator<T> {/*** 比较器接口要求的方法,参数是泛型参数,用户指定类型** @param o1 用户在使用接口时约束的泛型对应具体数据类型参数* @param o2 用户在使用接口时约束的泛型对应具体数据类型参数* @return 返回值为 int 类型,0 表示两个元素一致。*/int compare(T o1, T o2);
}

类型转换器接口

@FunctionalInterface
public interface Function<T, R> {R apply(T t);
}

方法设计

/**
* 将String类型字符串进行类型转换
*
* @param str 用户传入的字符串
* @param fun 类型转换器
* @return 返回转换的类型数据
*/
public static int testLambda(String str, Function<String, Integer> fun) {return fun.apply(str);
}

类型转换接口代码实现

public static void main(String[] args) {String str = "这里是类型转换接口";//当参数只有一个可以省略小括号,当代码实现只有一行可以同时省略return 和大括号int i = testLambda(str, s -> s.length());System.out.println(i);
}/**
* 将String类型字符串进行类型转换
*
* @param str 用户传入的字符串
* @param fun 类型转换器
* @return 返回转换的类型数据
*/
public static int testLambda(String str, Function<String, Integer> fun) {return fun.apply(str);
}

值得一提的是:

​ 当参数只有一个可以省略小括号,当代码实现只有一行可以同时省略return 和大括号

2.2.2 有参数无返回值Lambda

​ 这种接口一般被称为消费者接口,用户传入参数,然后参数在接口内部自己消化掉了

接口展示:

@FunctionalInterface
public interface Consumer<T> {void accept(T t);
}

方法设计

/*** 	消费性接口()* @param consumer	消费的规则* @param money	消费的数据*/
public static void play(Consumer<Integer> consumer,Integer money) {consumer.accept(money);
}

​ 这个方法设计比较简单,用户传入数据,然后被方法消费了。

消费者接口代码实现

public static void main(String[] args) {/*** 	消费型:Consumer<T>* 		使用数据,对类型为T的对象进行操作*///Lambdaplay(money -> System.out.println("一条龙花费:" + money), 666);//Lambdaplay(System.out::println, 666);}/*** 	消费性接口()* @param consumer	消费的规则* @param money	消费的数据*/
public static void play(Consumer<Integer> consumer,Integer money) {consumer.accept(money);
}
2.2.3无参数有返回值Lambda

​ 生产者接口,使用的数据都是对应方法的数据。

@FunctionalInterface
interface Supplier<T> {/*** 无参数有返回值方法,泛型约束的是接口对应的返回值数据类型,要求* 按照泛型约束返回对应的数据内容** @return 返回一个数据,符合泛型约束*/T get();
}

方法设计

/*** 	生成随机数组* @param supplier	供给型接口,在这里提供随机数* @param count		随机数的数量* @return*/
public static int[] getArr(Supplier<Integer> supplier,int count) {//创建数组int[] arr = new int[count];//添加数据for (int i = 0; i < arr.length; i++) {//添加数据arr[i] = supplier.get();}return arr;}

​ 这里设计了生成随机数据的方法,其中的数据内容可以自定义。

生产者接口代码演示:

public static void main(String[] args) {/*** 供给型接口Supplier<T>* 		返回类型为T的对象*/int[] arr = getArr(() -> new Random().nextInt(55) + 33, 10);System.out.println(Arrays.toString(arr));
}/*** 	生成随机数组* @param supplier	供给型接口,在这里提供随机数* @param count		随机数的数量* @return	返回一个int类型数组*/
public static int[] getArr(Supplier<Integer> supplier,int count) {//创建数组int[] arr = new int[count];//添加数据for (int i = 0; i < arr.length; i++) {//添加数据arr[i] = supplier.get();}return arr;	
}
2.2.4无参数无返回值Lambda

这种接口一般没什么用处,因为不需要传入参数,也没有返回值要获得。

二、Stream流

1.概述

首先需要明确的是,Stream流是在1.8版本及以上支持的。

1.stream的功能:

​ stream流可以对数据进行筛选,去重,按照规则排序,限制个数,跳过指定个数,最终处理等等,并且stream在对数据进行操作的时候不会对原始数据进行修改。

2.stream流的获取:

  • collection集合stream()方法
  • Arrays的stream方法

2.Stream流相关方法

stream流操作的是集合或者数组,以下方法可以获取stream流对象。

// 集合对象
Stream<T> stream();集合对象调用可以直接获取对应当前集合存储元素的 Stream 流对象。// 数组
Stream<T> Arrays.Stream(T[] t);利用 Arrays 工具类对当前需要按照 Stream 流方式操作的数据进行转换操作,根据当前数组的数据类型和数据存储情况,返回一个对应的 Stream 流对象

​ 我们可以对stream流对象进行许多中间操作,例如:skip跳过,limit限制个数,sorted排序,filter过滤,distinct去重,map类型转换。,方法的详细解释如下:

Stream<T> skip(long n);限制跳过当前 Stream 流对应元素的个数,【掐头】
Stream<T> limit(long n);限制当前 Stream 对应的元素总个数,【去尾】Stream<T> sorted();对当前 Stream 流存储的进行排序操作,要求元素有自然顺序或者遵从 Comparable 接口,默认【升序】
Stream<T> sorted(Comparator<? super T> com);对当前 Stream 流存储的进行排序操作,排序规则由 Comparator 函数式接口规范Stream<T> filter(Predicate<? super T> pre);判断过滤当前 Stream 流可以保存的数据条件,满足条件保留,不满足条件移除,过滤规则由 Predicate 接口约束Stream<T> distinct();当前 Stream 流中对应的所有元素去重擦操作Stream<R> map(Function<T, R> fun);当前 Stream 存储的数据情况转换为 Function 函数式接口要求的返回值类型,完成类型转换操作。

​ 执行stream流的终止方法,stream流会自动关闭,对应stream占用空间会被JVM收回。常用的stream流终止方法有count计数,forEach,collect存储为集合,toArray转换为object类型数组。

方法的详细解释如下:

long count();返回当前 Stream 流对应的数据元素个数,为终止方法。void forEach(Consumer<? super T> con);针对于当前 Stream 存储元素的处置方法,为终止方法。<R, A> R collect(Collector<? super T, A, R> collector);Stream 流对应的元素存储内容,转换为用户要求的 集合对象。终止方法常用:Collectors.toList() 目标存储集合类型为 List 集合Collectors.toSet()  目标存储集合类型为 Set 集合Object[] toArray();Stream 流存储的元素内容转换为 Object 类型数组返回

3.相关代码演示

skip 和 limit

list.stream().skip(3).limit(14).forEach(System.out::println);

​ 上述代码,创建集合的stream流,并对其中的数据进行跳过头三条数据,限制元素个数14的操作,相当于掐头去尾。

sort

ArrayList<Person> list = new ArrayList<>();for (int i = 0; i < 10; i++) {list.add(new Person("张三", (int) (Math.random() * 30), false));
}/*Stream<T> sorted(Comparator<? super T> comparator);@FunctionalInterfacepublic interface Comparator<T> {int compare(T o1, T o2);}*/
list.stream().sorted((p1, p2) -> p2.getAge() - p1.getAge()).forEach(System.out::println);
对集合中的Person对象按照年龄排序。p2.getAge() - p1.getAge()返回int类型数据,0是代表相等,正负代表升降序。

filter

/*
Stream<T> filter(Predicate<? super T> predicate);@FunctionalInterfacepublic interface Predicate<T> {boolean test(T t);}*/
list.stream().filter(s -> s.length() > 3).distinct().forEach(System.out::println);

​ 对s参数的长度进行过过滤,长度小于等于3的舍弃。

map

ArrayList<Person> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {int age = (int) (Math.random() * 50);list.add(new Person("张三", age, false));//  Stream<Person> stream = list.stream();
//  Stream<String> stream1 = stream.map(s -> s.toString());list.stream().map(s -> s.getAge()).limit(7).filter(s -> s > 40).forEach(System.out::println);

​ Lambda表达式s代表的是Person对象,返回值为存储s.getAge()的String对象,进行了类型转换,这里通过返回值约束泛型。

collect

List<String> list1 = list.stream().distinct().collect(Collectors.toList());Set<String> collect = list.stream().limit(21).collect(Collectors.toSet());

collect返回list或者set集合,stream流结束。

​ 最后值得注意的是,最终方法有且只可以用一次,如果多次使用,就会报异常:stream has already been operated upon or closed,提示当前Stream流已经关闭。

更多推荐

教你会用Lambda和Stream流

本文发布于:2024-03-13 07:11:24,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1733439.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:教你   会用   Stream   Lambda

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!