当前位置: 首页 > news >正文

【Java从入门到放弃 之 Stream API】

Java Stream API

  • Stream API
    • 行为参数化传递代码
    • Lambda表达式
      • Lambda 表达式的语法
      • 方法引用
    • Lambda 表达式的实际应用
      • 集合操作
      • 并发编程
    • Lambda 表达式的注意事项
    • 总结

Stream API

Java8提供了一个全新的API - Stream。引入这个Stream的主要目的,一个是可以支持更好的并发;一个是通过使用Stream可以向方法传递代码(更简洁的形式)

        Collections.sort(list, new Comparator<Stu>() {@Overridepublic int compare(Stu o1, Stu o2) {return o1.score - o2.score;}});

之前如果我们想给函数传递代码,需要通过匿名类的形式,可以看见这种形式比较繁琐。使用Java8的写法如下

        Collections.sort(list, (o1, o2) -> o1.score - o2.score);

是不是马上就简单了很多呢!

行为参数化传递代码

** 更好地传递代码 **

class Stu {private int age;private int score;public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getScore() {return score;}public void setScore(int score) {this.score = score;}
}
    public static List<Stu> filterScoreBigThan60(List<Stu> list) {List<Stu> ret = new ArrayList<>();for (Stu stu : list) {if (stu.getScore() > 60) {ret.add(stu);}}return ret;}public static List<Stu> filterAgeMoreThan15(List<Stu> list) {List<Stu> ret = new ArrayList<>();for (Stu stu : list) {if (stu.getAge() > 15) {ret.add(stu);}}return ret;}

我们自定义了一个Stu类,下面写了两个静态方法,用来过滤Stu的。观察这两段静态方法的代码,你发现什么了吗?
没错,我们会发现,这两段代码高度地相同。如果我们现在要再写一个过滤超过80分地学生,难道要在把代码复制粘贴一边?这肯定不是很好的实现方式,因为相同代码过多,我们一旦粘贴复制,很有可能会出现忘改某一些地方的情况 如果你现实中做过开发,搞过这种类似需求的代码,你一定明白我说的是啥。复制代码,但是某一些关键要改的地方不小心给漏掉了。而且每一个条件都要新建一个函数,会非常繁琐,函数名也会变得越来越长。

ok,问题我们是知道了,怎么解决了?

  1. 使用策略模式解决
        filterStuByInterface(list, new MyPredicate() {@Overridepublic boolean test(Stu stu) {return stu.getAge() > 60;}});public static List<Stu> filterStuByInterface(List<Stu> list, MyPredicate predicate) {List<Stu> ret = new ArrayList<>();for (Stu stu : list) {if (predicate.test(stu)) {ret.add(stu);}}return ret;}

我们把一组策略封装到一个策略里面,这里面使用的一个接口。所有的策略都实现这个接口。这样我们的方法就是通用的,每次使用的时候只要传入对应的策略就可以了。

  1. 使用Lambda表达式解决
    public static List<Stu> filterSte(List<Stu> list, Predicate<Stu> predicate) {List<Stu> ret = new ArrayList<>();for (Stu stu : list) {if (predicate.test(stu)) {ret.add(stu);}}return ret;}

Predicate predicate这个是什么意思呢?Predicate是一个泛型接口,里面有一个test用来返回boolean值。

@FunctionalInterface
public interface Predicate<T> {boolean test(T t);
}

我们随便通过使用策略模式也可以解决问题,但是通过对比Lambda表达式,我们发现Lambda表达式表达地更加简洁易懂。

Lambda表达式

Lambda 表达式是 Java 8 引入的一项重要特性,它使得代码更加简洁和易读,尤其是在处理集合、并发编程等方面。Lambda 表达式允许你以更函数式的方式编写代码,而不需要显式地创建匿名内部类。

Lambda 表达式的语法

Lambda 表达式的语法非常简洁,通常包括三个部分:参数列表、箭头符号(->)、方法体。

	(parameters) -> expression或(parameters) -> { statements; }

方法引用

方法引用是一种简化 Lambda 表达式的方式,当 Lambda 表达式只是调用一个已有的方法时,可以使用方法引用来代替 Lambda 表达式。方法引用有以下几种形式:

  • 静态方法引用:ClassName::staticMethod
  • 实例方法引用:instance::instanceMethod
  • 特定类型的方法引用:Type::method
  • 构造方法引用:ClassName::new

Lambda 表达式的实际应用

集合操作

Java 8 引入了流(Stream API),它可以与 Lambda 表达式一起使用,从而简化集合的操作,如过滤、映射、排序等。

	List<String> names = Arrays.asList("Alice", "Bob", "Charlie");// 过滤出长度大于 5 的名字,并转换为大写List<String> filteredNames = names.stream().filter(name -> name.length() > 5).map(String::toUpperCase).collect(Collectors.toList());System.out.println(filteredNames); // 输出 [CHARLIE]

并发编程

	ExecutorService executor = Executors.newFixedThreadPool(4);executor.submit(() -> {try {Thread.sleep(1000);System.out.println("Task completed by " + Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}});executor.shutdown();

Lambda 表达式的注意事项

  • 访问外部变量:Lambda 表达式可以访问外部的局部变量,但这些变量必须是有效的最终变量(effectively final),即它们在初始化后不能被修改。
  • 多线程安全:虽然 Lambda 表达式本身是线程安全的,但如果它操作共享资源,则需要考虑同步问题。
  • 性能:Lambda 表达式通常比匿名内部类更高效,因为它们避免了额外的类加载和内存分配。

总结

Lambda 表达式是 Java 8 引入的一个强大特性,它使代码更加简洁、易读,并且促进了函数式编程风格的应用。通过 Lambda 表达式,你可以更方便地处理集合、并发编程等问题。希望这些介绍和示例能帮助你更好地理解和使用 Lambda 表达式。如果有任何具体问题或需要进一步的帮助,请随时提问!

http://www.lryc.cn/news/497538.html

相关文章:

  • Ruby On Rails 笔记1——Rails 入门
  • 高效开发 Python Web 应用:FastAPI 数据验证与响应体设计
  • 基于“开源 2+1 链动 O2O 商城小程序”的门店拉新策略与流程设计
  • 33.5 remote实战项目之设计prometheus数据源的结构
  • 微服务springboot详细解析(一)
  • 深入探讨Go语言中的双向链表
  • Fastapi + vue3 自动化测试平台---移动端App自动化篇
  • ElasticSearch easy-es 聚合函数 group by 混合写法求Top N 词云 分词
  • 在 ASP.NET C# Web API 中实现 Serilog 以增强请求和响应的日志记录
  • 2024年顶级小型语言模型前15名
  • 精通 Python 网络安全(一)
  • 【python自动化二】pytest集成allure生成测试报告
  • 网络版本的通讯录青春版(protobuf)
  • 开源模型应用落地-安全合规篇-用户输入价值观判断(三)
  • 神经网络入门实战:(十四)pytorch 官网内置的 CIFAR10 数据集,及其网络模型
  • 【Rust在WASM中实现pdf文件的生成】
  • 在MySQL中执行sum case when报错:SUM does not exist
  • 【openssl】相关指令
  • 实例分割详解
  • D87【python 接口自动化学习】- pytest基础用法
  • 浅谈MySQL路由
  • matlab中disp,fprintf,sprintf,display,dlmwrite输出函数之间的区别
  • 30.100ASK_T113-PRO 用QT编写视频播放器(一)
  • Linux-GPIO应用编程
  • opencvocr识别手机摄像头拍摄的指定区域文字,文字符合规则就语音报警
  • 微服务即时通讯系统(5)用户管理子服务,网关子服务
  • postgreSQL安装后启动有The application server could not be contacted问题
  • 架构05-架构安全性
  • 虚幻引擎---材质篇
  • NPM镜像详解