Java-lambda表达式与流处理

news2025/1/31 20:00:17

文章目录

    • 一、lambda表达式
    • 二、方法引用
    • 三、Stream流

一、lambda表达式


在Java中,Lambda表达式是一种函数式编程的特性,它允许以简洁的语法编写函数或操作,而无需显式创建匿名类。Lambda表达式在Java 8中引入,是使Java更适应现代编程风格和需求的重要工具。lambda表达式可以代替简单的匿名内部类的实现。

lambda表达式的一个重要作用就是能够简写代码

需要注意的是,lambda表达式只适用于函数式接口,也就是接口内只定义了一个方法的接口。

如果一个接口是函数式接口一般会使用 @FunctionalInterface 来表示。

例如:forEach遍历中的接口就是一个函数式接口。
在这里插入图片描述



lambda表达式语法

(parameters) -> { statements; }
  • parameters:这是Lambda表达式的参数列表。参数类型是可选的,也可以直接推断。例如,a -> a + 1 和 (int a) -> a + 1 是等效的。
  • ->:这是Lambda操作符,将参数列表和Lambda体分开。
  • expression:这是Lambda体的单个表达式。如果Lambda体包含多个语句,则它们必须被大括号 {} 包围。

需要了解的是在实现 lambd表达式时可以按规则来简写lambda表达式

  1. 在小括号()内,如果只有一个形参,或者形象类型只有一种,那么形参类型可以省略
  2. 在大括号内{},如果只有一条语句,那么 大括号可以省略、return可以省略、分号也可以省略。

以下通过具体案例来说明这个简写规则。

首先先定义一个set集合,我们都知道set集合是无索引的,那么set集合常规的遍历方式只有迭代器遍历与forEach遍历。

Set<String> s=new HashSet<>();
// set集合:无序、不重复、无索引
s.add("张三");
s.add("李四");
s.add("王五");

1、迭代器遍历

// 迭代器方式遍历set集合
        // 创建迭代器
        Iterator<String> it = s.iterator();
        // 判断当前迭代器指针是否指向最后一个位置
        while(it.hasNext()){
            // 返回迭代器指针当前指向的元素,并且移动迭代器指针
            String str = it.next();
            System.out.println(str);
        }

2、forEach遍历

// foreach循环遍历set集合
        for(String i : s){
            System.out.println(i);
        }

以上两种遍历方式都能实现遍历set集合的要求,但是代码还是不够简洁,以下我们来通过从匿名内部类到lambda表达式的改进。

匿名内部类

//完整版
        s.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

lambda表达式

s.forEach((String i) -> {
            System.out.println(i);
});

根据简化规则的lambda表达式

s.forEach((o1) -> System.out.println(o1) ); //极简版

以上效果都是一样的,但是可以看到lambda表达式的代码结构清晰了许多,这就是lambda表达式的作用。



二、方法引用

在Java中,方法引用是一种简化Lambda表达式的方式,它允许你直接引用现有的方法,而不是重新定义一个Lambda表达式。

方法引用在Java 8中引入,它是一种非常方便的语法糖,可以使代码更加简洁、易读。

常用的方法引用分为引用静态方法、引用成员方法等。


1、引用静态方法

语法:类名 :: 静态方法名,这里出现的新操作符 :: 这是英文状态的冒号组成的。
需要注意的是这个语法中方法名是没有圆括号的。

例如:

List<String> list = Arrays.asList("A", "B", "C");  
list.forEach(System.out::println);

在上面的例子中,System.out::println 是一个方法引用。它引用了 System.out 类的静态方法 println。这个方法接受一个参数(在这个例子中是 String 类型),并打印这个参数。

引用静态方法规则

  1. 方法名和参数:在引用静态方法时,你需要提供方法的名称以及所需要的任何参数。例如,如果你有一个名为greet的静态方法,它需要一个字符串和一个整数作为参数,你可以这样引用它:ClassName.greet(参数1, 参数2)。
  2. 作用域:你可以在任何地方引用静态方法,包括在类的内部,其他类的内部,或者作为表达式的一部分。
  3. 访问权限:如果静态方法是私有的,那么你不能从类的外部访问它。如果它是受保护的,那么你可以从同一个包中的类或者其他包中的子类访问它。如果它是默认的(即没有修饰符),那么你可以从同一个包中的类访问它。
  4. 重载:你可以在一个类中拥有多个同名的静态方法,只要他们的参数列表不同(即形成了重载)。在引用时,Java会根据你提供的参数类型和数量来确定应该调用哪个方法。
  5. 泛型:虽然静态方法可以使用泛型,但是他们在引用时并不需要提供具体的类型参数。例如,如果你有一个名为calculate的静态方法,它需要一个List作为参数,你可以这样调用它:ClassName.calculate(myList),而不必提供类型参数。
  6. 访问静态方法的方式:你可以通过类名来访问静态方法,或者通过实例来访问(虽然这有些混淆,因为通常我们通过实例来调用实例方法,而不是静态方法)。例如,ClassName.methodName()或者instanceName.methodName()。
  7. 链式调用:如果一个静态方法的返回值是返回类型的实例,那么我们可以连续地调用这个实例的方法。例如,如果add方法返回一个Calculator实例,并且这个实例有一个calculate方法,那么我们可以这样使用:ClassName.add(1, 2).calculate()。

2、引用成员方法

引用对象的方法是指通过对象来引用其成员方法。

方法引用的语法格式为:object::methodName,其中object为对象实例,methodName为对象所属类中的成员方法名。

例如:

class Animal {  
    String name;  
  
    void makeSound() {  
        System.out.println("The animal makes a sound");  
    }  
}  
  
public class Main {  
    public static void main(String[] args) {  
        Animal animal = new Animal();  
        animal.name = "Cat";  
  
        // 引用对象方法  
        MethodReferenceDemo demo = new MethodReferenceDemo();  
        demo.printAnimalInfo(animal::makeSound, animal);  
    }  
}

在这个示例中,我们定义了一个Animal类,并在Main类中创建了一个Animal对象。我们使用animal::makeSound方法引用了Animal对象的makeSound方法。在printAnimalInfo方法中,我们使用Lambda表达式来处理被引用的方法,同时将Animal对象作为参数传递给该方法。

请注意,这里的MethodReferenceDemo和printAnimalInfo方法需要根据你的实际需求进行相应的实现。

需要注意的是,方法引用的目标必须是只有一个没有参数的方法或多个具有相同参数的方法。如果目标只有一个已命名的参数,则无法使用方法引用,只能使用Lambda表达式。



三、Stream流

Java中的Stream流是一种新的特性,它提供了一种处理集合和数组的方式,可以极大地方便我们对集合、数组等数据源进行连续操作。Stream流可以让我们以一种更加简洁、高效、可读性更强的方式来处理数据。

Stream流的操作可以分为中间操作终止操作两种类型。中间操作返回的是一个新的Stream流,而终止操作返回的是一个非Stream类型的结果
在Stream流的处理过程中,数据是惰性求值的,只有在执行终止操作时才会开始处理数据。这种处理方式可以减少计算量和开销,提高效率。

创建Stream流可以从很多种数据源中创建,例如List、Set或者任何其他实现了Iterable接口的类。创建方式很简单,使用stream()或parallelStream()方法即可。

总的来说,Stream流是一种方便、简洁且高效的数据处理方式,它可以使代码更加简洁易懂,提高代码的可读性和可维护性。


常用的中间操作方法

 /*
   filter:为过滤方法,方法中形参为lambda表达式或实现类
   stream流只能使用一次,建议使用链式编程
   修改流中的数据,不会改变原数组或集合的值,类似于拷贝了一份进行操作而已
   limit:获取stream流中前几个元素,形参为个数
   skip:跳过stream流中形参个元素。
   distinct:去重方法,当stream对象为自定义方法时,那么需要重写hashcode与equals方法
   concat:合并两个stream流
   map:转换流中数据类型
*/

常用的终止方法

 /*
   总结方法:
   froEach方法,遍历
   count:统计
   toArray:将流中数据转换为指定类型数组进行返回。
   collect:将流中数据收集进一个集合进行返回
*/

需要注意的是,在进行流处理的时候,中间方法与终止方法的区别在于中间方法会返回一个新的stream流,可以需要调用,而终止方法返回的是一个非stream流的结果。所以stream一般适合链式调用。



示例1: 使用stream流将List集合中的数据添加到map集合中,姓名做键,年龄做值。

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class 方法 {
    public static void main(String[] args) {
        /*
            总结方法:
            froEach方法,遍历
            count:统计
            toArray:将流中数据转换为指定类型数组进行返回。
            collect:将流中数据收集进一个集合进行返回
         */
        List<String> list=new ArrayList<>();
        Collections.addAll(list,"张无忌-男-18","wuhu-男-20","呀呼-女-20");

        // 匿名内部类实现stream流
        Map<String, String> user = list.stream().collect(Collectors.toMap(new Function<String, String>() {

                                                                                 @Override
                                                                                 public String apply(String s) {
                                                                                     return s.split("-")[0];
                                                                                 }
                                                                             }
                        , new Function<String, String>() {
                            @Override
                            public String apply(String s) {
                                return s.split("-")[2];
                            }
                        }
                )
        );

        // lambda实现stream流
        Map<String, String> user2 = list.stream().collect(Collectors.toMap(o1 -> o1.split("-")[0], o2 -> o2.split("-")[2]));

        user.forEach((o1,o2) -> System.out.println(o1+","+o2));
        System.out.println(user2);
    }
}

运行结果:

在这里插入图片描述

以上方法都是使用到了流处理的中间方法与终结方法。

具体查阅Java1.8Api文档。


END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1094032.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ从0到1完整学习笔记一:《基础篇》

目录 启篇 一、初识MQ 1.1 同步调用 1.2异步调用 1.3 技术选型 二、RabbitMQ 架构 2.2 收发消息 2.2.1 交换机 2.2.2 队列 2.2.3 绑定关系 2.2.4 发送消息 2.3 数据隔离 2.3.1 用户管理 2.3.2 virtual host 三、SpringAMQP 3.1 案例入门 3.1.1 导入依赖 3.1.2 消息发送 3.1.2 消…

IIS 部署.NetCore,最细步骤

服务器安装环境 将.net core程序部署到IIS总体需要经过以下3个大步骤&#xff0c;其中在IIS上配置网站有些比较繁琐&#xff0c;我都会逐一给出详细步骤。 <1>安装IIS和.NetCORE运行时程序 <2>以文件的形式发布.NETCORE程序到指定目录 <3>IIS上面建立网站…

【BiLSTM-Adaboost预测】基于双向长短期记忆网络的Adaboost时间序列预测研究(matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【LeetCode: 137. 只出现一次的数字 II | 位运算 | 哈希表】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

综述:大规模小目标检测

论文地址: Towards Large-Scale Small Object Detection: Survey and Benchmarks​arxiv.org/abs/2207.14096 目录 摘要 1.Introduction 1.1 与之前综述的比较 1.2 总结 2.小目标检测回顾 2.1 问题定义 2.2 主要挑战 2.3 小目标检测算法回顾 3.小目标检测的数据集 …

java网上商城购物网站管理系统69bz5 用户 会员springboot+vue

主要目的是通过网络平台方便商家进行商品订单管理并让客户有更好的购物体验。以商家在后端提供商品供客户在前端商城选购&#xff0c;客户将所需的商品加入购物车&#xff0c;然后通过结算购物车功能填写相应信息生成订单&#xff0c;付款以后再由商家在后端接收到订单进行处理…

自动驾驶中的数据安全和隐私

自动驾驶技术的发展已经改变了我们的出行方式&#xff0c;但伴随着这项技术的普及&#xff0c;数据安全和隐私问题也变得愈发重要。本文将探讨自动驾驶中的数据收集、数据隐私和安全挑战&#xff0c;以及如何保护自动驾驶系统的数据。 自动驾驶中的数据收集 在自动驾驶技术中…

深入理解 JVM(重点:双亲委派模型 + 垃圾回收算法)

一、什么是 JVM&#xff1f; JVM 是 Java Virtual Machine 的简称&#xff0c;意为 Java虚拟机。虚拟机是指通过软件模拟的具有完整硬件功能的、运行在一个完全隔离的环境中的完整计算机系统。可以认为 JVM 是一台被定制过的现实当中不存在的计算机&#xff0c;Java程序最终是…

Tuxera NTFS for Mac2024最新中文版本下载

如果你想用U盘在Mac和其他设备之间传输文件&#xff0c;可能会遇到一些问题。因为Mac系统支持的U盘格式和其他系统不同&#xff0c;而且苹果电脑对U盘的读写权限也有一定的限制。那么&#xff0c;Mac系统支持什么格式的U盘呢&#xff1f;苹果电脑读写权限怎么开启呢&#xff1f…

前端打包项目上线-nginx

第一步&#xff1a;下载nginx。 直接下载 nginx/Windows-1.25.2 pgp 第二步&#xff1a;解压zip包 第三步&#xff1a;打开文件夹&#xff0c;把http里的路径打开cmd 第四步&#xff1a;打开你的http-server服务&#xff0c;没有下载去下一次就ok了 打开后就可以访问了 第五步…

黑豹程序员-页面录音-在vue页面中进行录音wav/mp3

功能 在vue页面中进行录音wav/mp3 效果图 官网展示页面 https://recorder.zhuyuntao.cn/ 安装组件 npm i js-audio-recorder 测试页面 <template><h3>录音时长&#xff1a;{{ recorder.duration.toFixed(4) }}</h3><el-row><el-button type…

QE01/QA11/QA02屏幕增强

1、业务需求 需要对来料检验增加“合格数量”和“不合格数量”字段&#xff0c;涉及三个增强开发 2、QE01\QE02\QE03\QE51N屏幕增强 增强表 增强点BADI&#xff1a;QEEM_SUBSCREEN_5000 创建程序&#xff0c;包含子屏幕&#xff0c;在增强点中调用 在程序屏幕中绘制字段 在输…

【CNN-GRU预测】基于卷积神经网络-门控循环单元的单维时间序列预测研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Redux 错误处理

Redux 错误处理 这两天正好收尾一个 Redux 页面的重构&#xff0c;碰到了一些错误处理的方式&#xff0c;这里就写个笔记总结一下碰到的问题和几种处理方式 大体上是分为同步函数和异步函数两个方面去处理 同步函数 这个是指的是直接在 reducer 中进行操作&#xff0c;可以…

基于springboot实现医疗服务系统项目【项目源码+论文说明】计算机毕业设计

摘要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 医疗服务系统&#xff0c;主要的模块包括查看管理员&#xff1b;首页、个人中心、普通村民管理、乡村医生管理、公告信息管理、乡村诊室管理、…

抖音店铺提供优质服务|成都瀚网科技

抖音是中国领先的电子商务平台。为了帮助商家增加销量和品牌曝光度&#xff0c;抖音推出了精选联盟计划。精选联盟是由优质商家组成的联盟&#xff0c;旨在为消费者提供更多优质、高性价比的产品选择。那么&#xff0c;如何使用抖店开通精选联盟呢&#xff1f;这将在下面详细描…

计算机中了360后缀勒索病毒怎么办?360勒索病毒解密数据恢复

最近一段时间360后缀勒索病毒变得异常嚣张&#xff0c;时不时就会攻击企业的计算机服务器&#xff0c;导致众多的企业服务器被360后缀勒索病毒攻击。360后缀的勒索病毒并非360公司&#xff0c;是黑客专门具有针对性地研发的勒索病毒&#xff0c;通过加密企业的计算机给企业带来…

Docker容器与虚拟化技术:DaoCloud账户注册

目录 一、实验 1.DaoCloud 一、实验 1.DaoCloud &#xff08;1&#xff09;概念 DaoCloud是企业级容器云平台&#xff0c;它提供了一套容器集群解决方案&#xff0c;Daocloud可以管理你的计算资源&#xff0c;包括物理机和公有云环境&#xff0c;你可以在DaoCloud平台上部…

基于springboot实现音乐网站与分享平台项目【项目源码+论文说明】计算机毕业设计

摘要 本论文主要论述了如何使用JAVA语言开发一个音乐网站与分享平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述音乐网站与分享平台的当前背景以及系统开…

C++桶排序算法的应用:存在重复元素 III

题目 给你一个整数数组 nums 和两个整数 indexDiff 和 valueDiff 。 找出满足下述条件的下标对 (i, j)&#xff1a; i ! j, abs(i - j) < indexDiff abs(nums[i] - nums[j]) < valueDiff 如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例…