在我们看他人code的时候经常会看到,可能会经常看到lambda表达式,函数式接口,以及流式计算。在刚接触这些新功能时,也觉得真的有必要吗?但是现在写多了,发现这个功能确实能简化代码结构,提升编码效率。lambda表达式,函数式接口,流式计算单个来用确实非常难用,但是整合到一起,就会发生非常奇妙的反应。

lambda表达式

lambda表达式允许把函数作为一个方法的参数。即,函数作为参数传递进方法。

lambda语法

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

lambada表达式的几个重要特征:

  • 可选类型声明:不需要申明参数类型,编译器可以统一识别参数类型
  • 可选参数圆括号:一个参数无需定义圆括号。但是多个参数需要定义圆括。
  • 可选大括号:如果主体只包含了一个语句,就不需要使用大括号。
  • 可选返回关键字:如果主体只有一个表达式返回值,编译器会自动返回值。
// 1. 不需要参数,直接返回值
() -> 3 // 2. 接收一个参数,返回其两倍
x -> 2 * x // 3. 接收两个数字, 返回差
(x, y) -> x - y

函数式接口

什么是函数式接口

函数式接口就是有且仅有一个抽象方法的接口。(但是可以有多个非抽象方法)。

函数式接口可以被转换为lambda表达式。

四大函数式接口

java.util.function.Consumer

// 消费者:接收一个参数,没有返回值
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
-----------------------------------------------------------------------------
java.util.function.Predicate // 断言者:接收一个参数,返回一个boolean
@FunctionalInterface
public interface Predicate<T> { /**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
----------------------------------------------------------------------------------
java.util.function.Supplier // 提供者:不接受任何参数,返回会一个参数
@FunctionalInterface
public interface Supplier<T> { /**
* Gets a result.
*
* @return a result
*/
T get();
}
--------------------------------------------------------------------------------
java.util.function.Function
// 操作者:接收一个参数,返回一个参数
@FunctionalInterface
public interface Function<T, R> { /**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}

下面我们来看看,lambda和函数式接口的使用。

package com.hardy;

import org.junit.Test;

import java.util.function.Consumer;
import java.util.function.Predicate; /**
* @description:
* @author: Administrator
* @time: 2022/8/21
*/
public class FunctionTest { @Test
public void testConsumer(){
Consumer<Object> consumer = new Consumer<>() { @Override
public void accept(Object o) {
System.out.println(o);
}
};
consumer.accept("test");
System.out.println("--------------------");
// lambda
Consumer<String> lc = (s) -> {
System.out.println(s);
};
lc.accept("lambda");
System.out.println("--------------------");
// lambda
Consumer<String> lc2 = (s) -> {
System.out.println(s);
};
lc2.accept("lambda2");
System.out.println("--------------------");
// lambda
Consumer<String> ll = System.out::println;
ll.accept("ll");
} @Test
public void testPredicate(){
Predicate<Integer> predicate = new Predicate<>() {
@Override
public boolean test(Integer o) {
if (o > 60) {
return true;
} else {
return false;
}
}
};
System.out.println(predicate.test(61));
System.out.println("--------------------------");
Predicate<Integer> predicate1 = i -> {
return i > 60;
};
System.out.println(predicate1.test(50));
}
}

如果只看lambda表达式,函数式接口,你也许会感觉就那么回事,感觉也没啥好的。但是,当你看到流式计算,你才会体会到lambda表达式和函数式接口给编程带来的简洁。

流式计算

思考:如何使用一行代码实现,下列要求:

  1. 对象的年龄大于18
  2. 性别为男性
  3. id为偶数
  4. id 倒序排列
  5. name字母大写
public class StreamTest {

    /**
* 1. 对象的年龄大于18
* 2. 性别为男性
* 3. id为偶数
* 4. id 倒序排列
* 5. name字母大写
*/
@Test
public void testStream() {
// 这里模拟从数据库获取数据
User u1 = new User(1, "name1", "male", 16);
User u2 = new User(2, "name2", "female", 17);
User u3 = new User(3, "name3", "male", 18);
User u4 = new User(4, "name4", "male", 19);
User u5 = new User(5, "name5", "male", 26);
User u6 = new User(6, "name6", "male", 35);
User u7 = new User(7, "name7", "male", 19);
User u8 = new User(8, "name8", "female", 12); // 集合
List<User> list = Arrays.asList(u1, u2, u3, u4, u5, u6, u7, u8); // stream
List<User> users = list.stream().filter(user -> user.getAge() > 18)
.filter(user -> user.getSex().equals("male"))
.filter(user -> user.getId() % 2 == 0)
.sorted(Comparator.comparingInt(User::getId))
.peek(user -> user.setName(user.getName().toUpperCase())).collect(Collectors.toList());
System.out.println(users);
}
}

记住:存储交给集合,计算交给流

Java的lamda表达式/函数式接口/流式计算的更多相关文章

  1. 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)

    小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优)  //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ...

  2. 流式计算新贵Kafka Stream设计详解--转

    原文地址:https://mp.weixin.qq.com/s?__biz=MzA5NzkxMzg1Nw==&mid=2653162822&idx=1&sn=8c4611436 ...

  3. 流式计算(一)-Java8Stream

    大约各位看官君多少也听说了Storm/Spark/Flink,这些都是大数据流式处理框架.如果一条手机组装流水线上不同的人做不同的事,有的装电池,有的装屏幕,直到最后完成,这就是典型的流式处理.如果手 ...

  4. Others-阿里专家强琦:流式计算的系统设计和实现

    阿里专家强琦:流式计算的系统设计和实现 更多深度文章,请关注云计算频道:https://yq.aliyun.com/cloud 阿里云数据事业部强琦为大家带来题为“流式计算的系统设计与实现”的演讲,本 ...

  5. 分布式流式计算平台——S4

    本文是作者在充分阅读和理解Yahoo!最新发布的技术论文<S4:Distributed Stream Computing Platform>的基础上,所做出的知识分享. S4是Yahoo! ...

  6. 流式计算(三)-Flink Stream 篇一

    原创文章,谢绝任何形式转载,否则追究法律责任! ​流的世界,有点乱,群雄逐鹿,流实在太多,看完这个马上又冒出一个,也不知哪个才是真正的牛,据说Flink是位重量级选手,能流计算,还能批处理, 和其他伙 ...

  7. Stream流式计算

    Stream流式计算 集合/数据库用来进行数据的存储 而计算则交给流 /** * 现有5个用户,用一行代码 ,一分钟按以下条件筛选出指定用户 *1.ID必须是偶数 *2.年龄必须大于22 *3.用户名 ...

  8. Apache Beam—透视Google统一流式计算的野心

    Google是最早实践大数据的公司,目前大数据繁荣的生态很大一部分都要归功于Google最早的几篇论文,这几篇论文早就了以Hadoop为开端的整个开源大数据生态,但是很可惜的是Google内部的这些系 ...

  9. 大数据学习:storm流式计算

    Storm是一个分布式的.高容错的实时计算系统.Storm适用的场景: 1.Storm可以用来用来处理源源不断的消息,并将处理之后的结果保存到持久化介质中. 2.由于Storm的处理组件都是分布式的, ...

随机推荐

  1. sqlserver 把c#代码的string[] 的ids转换成一个数据table表

    declare @string varchar(200),@sql varchar(1000)set @string = '1,2,3,4,5,6'set @sql = 'select code='' ...

  2. AOP-动态代理

    动态代理的原理代理设计模式的原理:使用一个代理将原本对象包装起来,然后用该代理对象"取代"原始对象.任何对原始对象的调用都要通过代理.代理对象决定是否以及何时将方法调用转到原始对象 ...

  3. Detecting Rumors from Microblogs with Recurrent Neural Networks(IJCAI-16)

    记录一下,很久之前看的论文-基于RNN来从微博中检测谣言及其代码复现. 1 引言 现有传统谣言检测模型使用经典的机器学习算法,这些算法利用了根据帖子的内容.用户特征和扩散模式手工制作的各种特征,或者简 ...

  4. 用KVM安装MacOS/OSX

    基本步骤按照大牛的步骤https://github.com/kholia/OSX-KVM 黑果镜像建议用黑果小兵的:macOS Big Sur(我试过,大牛的更卡),里面的双EFI就很够用. 将镜像名 ...

  5. MySQL--用通配符进行过滤(LIKE操作符)

    1.LIKE操作符 怎样搜索产品名中包含文本anvil的所有产品?用简单的比较操作符肯定不行,必须使用通配符.利用通配符可创建比较特定数据的搜索模式.在这个例子中,如果你想找出名称包含anvil的所有 ...

  6. Grid属性太多记不住?【Grid栅格布局可视化编辑器】直观易懂高效,拖拉拽,有手就行!

    手把手教你通过拖拉拽可视化的方式带你练习[Grid栅格布局]的各个属性,直观易懂!再也不愁记不住繁多的Grid属性了.整个过程在众触应用平台进行,不用手写一行CSS代码. grid-auto-flow ...

  7. 关于python文件打包成exe的调试问题

    python文件使用pyinstaller打包的问题 常用pyinstaller相关命令 文件整体打包, 会自动打包相关依赖 pyinstaller -F file 分文件打包,只打包单个文件,其他文 ...

  8. 20220724-Java的封装相关

    目录 含义 常见使用方法 个人理解 含义 封装 (encapsulation) 指隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别. 常见使用方法 class Pers ...

  9. 别梦依稀咒逝川,Ruby二十八年前|M1芯片Mac os系统配置Ruby(3.0.0) on Rails(6.1.1)开发环境(2021最新攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_188 在每个开发者心里,都会有一门"最好"的语言,在这个世界的某个深处,在一些矫矫不群的人们心中,这门语言的名 ...

  10. uniapp中用canvas实现小球碰撞的小动画

    uniapp 我就不想喷了,踩了很多坑,把代码贡献出来让大家少踩些坑. 实现的功能: 生成n个球在canvas中运动,相互碰撞后会反弹,反弹后的速度计算我研究过了,可以参考代码直接用 防止球出边框 防 ...