JDK8新特性

34bcee8e9ad14dd48e9f5eb87eebd5ed.jpgLembda表达式

 

lembda表达式是一个简洁、可传递的匿名函数,实现了把代码块赋值给一个变量的功能

 

是我认为jdk1.8中最让人眼前一亮的特性(我没用过其他函数式的语言)

 

在了解表达式之前,我们先看两个概念

 

函数式接口

含有且仅含有一个抽象方法,Lembda表达式需要借助函数式接口实现。

 

通常来说我们在这个接口定义上加上@FunctionInterface注解,语义化地标注它是一个函数式接口,起到的作用和@Override相同,只起到检查作用。

 

允许对接口进行默认实现

这次更新中新增了一个default关键字,用来在接口中添加非抽象的方法实现。这个特性也被成为扩展方法。

 

在实际使用Lembda表达式的时候,我们通过表达式实现相应的接口得到接口的实现对象。我们可以直接通过这些对象调用接口中的默认实现。

 

Lembda表达式格式

Lembda表达式通过左侧的参数,右侧的表达式和中间的右箭头组成:

 

(parameter1,parameter12,...) -> {

 expression;

 ...

 return xxx;

}

可以理解为方法的另一种表现形式;

比如说这个接收a和b两个int参数,返回两数之和的方法

 

int addNum(int a,int b){

 return a + b;

}

可以写成下面这个形式

 

(int a,int b) -> {

 return a + b

}

需要注意的是:

 

参数可以为空 ()->xxx 这代表了无参方法

参数为一个值得时候,可以省略参数的括号 x->xxx

参数类型可以省略,Jdk会自动在接口中匹配相应的类型

表达式只有一行的时候不需要;,有多行的时候需要加上;

表达式可以是一个数字(直接返回这个数字),一个算式;可以是普通的一个语句(无返回,相当于void)

当表达式只有一行且最终为返回值时,return可以省略

参数的名不能和局部变量相同

表达式中直接调用的变量(不是传入的),必须是显示声明为final或事实上的final类型

自定义函数式接口并调用

我们定义一个入参是两个int类型,返回值也是int类型的方法;

 

然后添加一个将一个数加1并返回的扩展方法,使用default关键字;

 

@FunctionalInterface

interface Append {

    int append(int a, int b);

 

    default int addOne(int num) {

        return ++num;

    }

}

现在,我们使用Lambda表达式对这个接口进行实现:

 

Append append = (int a, int b) -> {

    return a + b;

};

然后我们调用这个方法,也调用接口的扩展方法

 

int num = append.append(1, 2);

int numAddOne = append.addOne(num);

System.out.println(num);//3

System.out.println(numAddOne);//4

根据上面总结的表达式格式注意事项,我们可以对表达式进行简化

 

当代码只有一行地时候可以不加分号

 

Append append = (int a, int b) -> { return a + b };

去掉参数类型,并且进一步简化右侧

 

Append append = (a, b) -> a + b;

方法调用

如果你使用的是IDEA较新版本,它会提示将它简化成另一种形式;

 

Append append = Integer::sum;

这是方法引用,在表达式中,我们可以通过类::方法的格式,直接将这个方法作为表达式的内容;

 

因此使用这种形式的时候无需指定参数,返回值等,因为这些已经确定了;

 

如果方法重载,jdk会根据传入的方法找到合适的方法

 

我们进入这个方法,发现它和我们的表达式相同

 

public static int sum(int a, int b) {

    return a + b;

}

我们还可以通过这种形式获得构造方法的调用

 

类::new

返回值就是通过合适构造方法(同样根据入参选择)创建的这个类的对象

 

Lambda表达式中变量的访问范围

外部final变量

成员变量

静态变量

需要注意,在表达式中无法访问接口的扩展方法

 

JDK自带的常用函数式接口

Predicate 判断,

boolean test(T t); 对单一参数进行判断,拓展方法可以对Predicate进行or,and的逻辑拼接,进行更复杂的逻辑判断

 

利用我们在外部设定的条件对于传入的参数进行校验并返回验证通过与否

 

Consumer 消费者

void accept(T t); 消费掉参数,啥也不返回,拓展方法可以拼接消费者链,按次序依次执行

 

接收参数并依据传递的行为应用传递的参数值

 

Function<T, R> 方法

R apoly(T t); ,该接口中有很多拓展方法,可以将多个Function拼接在一起,进行复杂的逻辑运算

执行转换操作,输入类型 T 的数据,返回 R 类型的结果

 

这三个是最重要的接口,Stream也用到这些接口,下面我强行使用这三个接口

 

    /*Predicate<T> 判断*/

    Predicate<String> stringPredicate = str -> StringUtils.isBlank(str) || "error".equalsIgnoreCase(str);

    

    /*Consumer<T>*/

    Consumer<String> stringConsumer = str -> {

        if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {

            System.out.println("Consumer失败");

        }

    };

    /*Function<T,R>*/

    Function<String, String> stringStringFunction = str -> {

        if (StringUtils.isBlank(str) || "error".equalsIgnoreCase(str)) {

            return "Function失败";

        } else {

            return "Function成功";

        }

    };

    String in = "error";

    if (stringPredicate.test(in)) {

        System.out.println("Predicate失败");

    }

    stringConsumer.accept(in);

    System.out.println(stringStringFunction.apply(in));

二.Stream流

Stream使用上面说的JDK自带的函数式接口

 

Stream是一种函数式编程对集合,数组,I/O channel, 产生器generator等数据的操作方式,它有以下特点:

 

无储存,Stream本身不会储存数据

不会修改传入的数据源

惰性执行:Stream上的操作不会立即执行,而是会在真正需要的时候进行

可消费性:Stream只能被消费一次,类似迭代器,想要再次遍历,必须生成新的Stream.

在学习过程中,我发现Stream某些操作之后返回的仍然是流,而有些操作返回的确实真实的被处理之后数据,Stream的操作可以据此分为两种

 

中间操作 总是会惰式执行,调用中间操作只会生成一个标记了该操作的新stream。

结束操作 会触发实际计算,计算发生时会把所有中间操作积攒的操作以pipeline的方式执行,这样可以减少迭代次数。计算完成之后stream就会失效。

总之,把Stream看做一根水管就好啦,一开始把一根根水管拼接起来(中间操作),安装一个水龙头(结束操作),确认有水龙头之后水就依次通过水管,最后通过水龙头进入下水道(不能重复使用);

 

Collection.stream() 或者 Collection.parallelStream() 来创建一个串行Stream或者并行Stream。

 

常用的Stream方法

 

中间操作

sorted排序

Stream<T> sorted();

Stream<T> sorted(Comparator<? super T> comparator);

 

这是一个有状态的操作

 

用法 作用

sorted() 自然排序

sorted(Comparator.reverseOrder()) 自然逆向排序

sorted(Comparator.comparing(Student::getAge)) 通过某些元素排序

sorted(Comparator.comparing(Student::getAge).reversed()) 通过某些元素逆向排序

Comparator是比较器

 

map元素操作

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

用于对每个元素进行操作,并且将处理后的Stream返回

例如map(i->i*2)将所有数据进行平方操作

 

filter过滤

Stream<T> filter(Predicate<? super T> predicate);

入参为Predicate,lembda表达式返回值是boolean;

如果表达式为flase,则剔除数据,只留符合条件的

过滤是中间操作:Stream<Integer> integerStream = intList.stream().filter(i -> i > 4);

 

limit限制

Stream<T> limit(long maxSize);

限制数据的数量,这是一个有状态的短路的操作。

 

distinct去重

Stream<T> distinct();

去除重复的操作,这是一个有状态的操作

 

结束操作

forEach迭代

void forEach(Consumer<? super T> action);

入参是Consumer,表达式不需要返回值,方法本身返回值void,所以是结束操作

常用的方法是forEach(System.out::println);

 

collect存入容器

<R, A> R collect(Collector<? super T, A, R> collector);

将数据存入一个Collection或Map

 

toArray存入数组

Object[] toArray();

将结果存入一个数组中

 

count计数

long count();

计算流中元素的数量

 

max 和 min

Optional<T> min(Comparator<? super T> comparator);

Optional<T> max(Comparator<? super T> comparator);

根据一个比较器找到最大或最小元素

 

anyMatch allMatch noneMatch 匹配

boolean anyMatch(Predicate<? super T> predicate);三个都一样

是否至少有一个元素匹配

是否每一个元素都匹配

是否没有元素匹配

 

findFirst findAny 查找

Optional<T> findFirst();

查找第一个元素

查找随机的一个元素

 

Stream常用代码

List转Map

 

Map<Integer, A> aMap = aList.stream().col

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

随手笔记(四十五)——idea git冲突

图片为引用&#xff0c;在一次导入项目至gitee的过程中&#xff0c;不知道为什么报了403&#xff0c;很奇怪的一个错误&#xff0c;网上很多的答案大概分成两种。 第一种是最多的&#xff0c;直接找到windows凭据删掉 很抱歉的告诉各位&#xff0c;你们很多人到这里就已经解…

Python基础数据结构入门必读指南

更多资料获取 作者主页&#xff1a;涛哥聊Python 个人网站&#xff1a;涛哥聊Python 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享的是Python中常见的数据结构。 1.数组 含义&#xff1a;数组是一种有序的数据结构&#xff0c;其中的元素可以按照索引来访问。数组…

30天入门Python(基础篇)——第2天:Python安装(保姆级)与IDE的认识与选择+详细安装教程

文章目录 专栏导读上一节课回顾1、Python解释器的安装查看各个版本的Python解释器①、ok,双击安装②、这里我们选择【自定义】安装&#xff0c; 下面的【将Python添加在环境变量】大家一定要打个勾③、点击【Next】进行下一步④、这里不建议安装在C盘, 点击【Browse】我在F盘创…

keil报错:Flash Download failed - Could not load file‘..\..\Output\Template.axf

keil报错&#xff1a;Flash Download failed - Could not load file’…\Output\Template.axf&#xff0c;如下图所示&#xff1a; 原因是很多.h文件没有定义位置&#xff0c;可以按照下图操作&#xff1a; 而且&#xff0c;如果是想使用压缩包&#xff0c;那一定要关闭keil后…

Android 数据库封装(SQLite)

Android 数据库操作&#xff08;SQLite&#xff09; Android 数据库操作&#xff08;SQLite&#xff09;动态预览使用初始化生成表实体类插入数据批量插入删除数据删除全部修改数据查找&#xff08;列表&#xff09;查找&#xff08;单条&#xff09;条件查找&#xff08;列表&…

算法刷题 week2

目录 week21. 二维数组中的查找题目题解(单调性扫描) O(nm) 2.替换空格题目题解(线性扫描) O(n)(双指针扫描) O(n) 3.从尾到头打印链表题目题解(遍历链表) O(n) week2 1. 二维数组中的查找 题目 题解 (单调性扫描) O(nm) 核心在于发现每个子矩阵右上角的数的性质&#xff1…

docker-compose使用

docker-compose docker的项目编排 一、安装docker-compose Rocky Linux Rocky Linux安装Docker Compose的步骤如下&#xff1a; 安装Docker。您可以使用以下命令安装Docker&#xff1a; sudo dnf install docker-ce docker-ce-cli containerd.io安装Docker Compose。您可以…

ChatGPT实战-Embeddings打造定制化AI智能客服

本文介绍Embeddings的基本概念&#xff0c;并使用最少但完整的代码讲解Embeddings是如何使用的&#xff0c;帮你打造专属AI聊天机器人&#xff08;智能客服&#xff09;&#xff0c;你可以拿到该代码进行修改以满足实际需求。 ChatGPT的Embeddings解决了什么问题&#xff1f; …

上海亚商投顾:三大指数小幅下跌 光刻机概念股午后走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日小幅调整&#xff0c;创业板指走势较弱。减肥药概念股继续大涨&#xff0c;常山药业2连板&#x…

linux( CentOs)对mysql基本操作和密码修改

1.mysql登录 mysql -uroot -p 2.显示所有数据库 Show databases; 3.生产过程中改密码 use mysql ; 查看user表中的user、host、password信息。 select user,host,password from user; select host,user from user;使用“GRANT ALL PRIVILEGES ON *.* TO root% IDENTIFIE…

Linux调试器-gdb使用

文章目录 前言一、pandas是什么&#xff1f;1、gdb介绍2、gdb使用2.1 启动gdb和退出gdb2.2 list显示代码命令2. run运行程序命令2.3 break设置断点命令2.4 delete删除断点命令2.5 next逐过程执行命令2.6 step逐语句向下执行命令2.7 print打印表达式值命令2.8 bt命令和finish命令…

初识C语言——详细入门一(系统性学习day4)

目录 前言 一、C语言简单介绍、特点、基本构成 简单介绍&#xff1a; 特点&#xff1a; 基本构成&#xff1a; 二、认识C语言程序 标准格式&#xff1a; 简单C程序&#xff1a; 三、基本构成分类详细介绍 &#xff08;1&#xff09;关键字 &#xff08;2&#xf…

插拔结构脉冲离子风工作原理

脉冲离子风机有着特殊的结构-插拔结构&#xff0c;清洁保养维修更简单、更安全&#xff1b;核心部件模块化&#xff1b;它有着超强的消除静电能。 脉冲台式离子风机的安装方法:将离子风机置于台面上或悬挂于台面上&#xff0c;插上电源插头&#xff0c;打开风机&#xff0c;调节…

微信群发一次能发1000个好友了!你发现了吗?

微信作为我们日常交流的主要工具之一 群发功能在我们的日常生活中也非常实用 但有时候 比如在新年期间 需要向所有客户发送祝福时 在公司做活动期间 向所有客户发起邀约时 如果一个一个点击来发送信息 会非常麻烦 但是&#xff01;&#xff01; 我今天发现微信 已经…

部署ik分词器

部署ik分词器 案例版本&#xff1a;elasticsearch-analysis-ik-8.6.2 ​ ES默认自带的分词器对中文处理不够友好&#xff0c;创建倒排索引时可能达不到我们想要的结果&#xff0c;然而IK分词器能够很好的支持中文分词 ​ 因为是集群部署&#xff0c;所以每台服务器中的ES都需…

HarmonyOS应用开发—资源分类与访问

应用开发过程中&#xff0c;经常需要用到颜色、字体、间距、图片等资源&#xff0c;在不同的设备或配置中&#xff0c;这些资源的值可能不同。 应用资源&#xff1a;借助资源文件能力&#xff0c;开发者在应用中自定义资源&#xff0c;自行管理这些资源在不同的设备或配置中的表…

C语言指针,深度长文全面讲解

指针对于C来说太重要。然而&#xff0c;想要全面理解指针&#xff0c;除了要对C语言有熟练的掌握外&#xff0c;还要有计算机硬件以及操作系统等方方面面的基本知识。所以本文尽可能的通过一篇文章完全讲解指针。 为什么需要指针&#xff1f; 指针解决了一些编程中基本的问题。…

9.19作业

TCP服务器 //创建流式套接字int sfd socket(AF_INET, SOCK_STREAM, 0);if(sfd < 0){ERR_MSG("socket"); return -1;}printf("socket create success sfd%d\n", sfd);//允许端口快速复用in…

MQTT Paho Android 支持SSL/TLS(亲测有效)

MQTT Paho Android 支持SSL/TLS(亲测有效) 登录时支持ssl的交互 这是调测登录界面设计 代码中对ssl/tls的支持 使用MqttAndroidClient配置mqtt客户端请求时&#xff0c;不加密及加密方式连接存在以下几点差异&#xff1a; url及端口差异 val uri: String if (tlsConnect…

[npm]脚手架本地全局安装1

[npm]脚手架本地全局安装1 npm link 全局安装npm install 全局安装卸载全局安装的脚手架 该文章是你的脚手架已经开发完成的前提下&#xff0c;你想要本地全局安装该脚手架&#xff0c;便于本地使用脚手架的命令的情况 npm link 全局安装 如果本地开发的项目是个脚手架&#…