Lambda8 表达式
Lambda 表达式
Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极大地优化代码结构。
JDK 也提供了大量的内置函数式接口供我们使用,使得 Lambda 表达式的运用更加方便、高效。
可以对某些匿名内部类的写法进行简化,它是函数式编程思想的一个重要体现,不用关注是什么对象,而是更关注对数据进行了什么操作。
基本格式
(参数列表)->{代码}
范例
范例一:
在创建线程并启动时可以使用匿名内部类的写法;
- 匿名内部类方式:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread());
}
}).start();
- Lambda方式:
new Thread(() -> {
System.out.println(Thread.currentThread());
}).start();
范例二:
IntBinaryOperator是一个接口,使用匿名内部类的写法调用该方法;
- 匿名内部类方式:
public static int calculateNum(IntBinaryOperator operator) {
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
@Test
public void testLambda2() {
int i = calculateNum(new IntBinaryOperator() {
@Override
public int applyAsInt(int left, int right) {
return left + right;
}
});
System.out.println(i);
}
- Lambda方式:
public static int calculateNum(IntBinaryOperator operator) {
int a = 10;
int b = 20;
return operator.applyAsInt(a, b);
}
@Test
public void testLambda2() {
int i = calculateNum((int left, int right) -> {
return left + right;
});
System.out.println(i);
}
范例三:
IntPredicate是一个接口。先使用匿名内部类的写法调用该方法;
- 匿名内部类方式:
public static void printNum(IntPredicate predicate) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
if (predicate.test(i)) {
System.out.println(i);
}
}
}
@Test
public void testLambda3() {
printNum(new IntPredicate() {
@Override
public boolean test(int value) {
return value % 3 == 0;
}
});
}
- Lambda方式:
public static void printNum(IntPredicate predicate) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
if (predicate.test(i)) {
System.out.println(i);
}
}
}
@Test
public void testLambda3() {
printNum((int value) -> {
return value % 3 == 0;
});
}
范例四:
Function是一个接口,先使用匿名内部类的写法调用该方法;
- 匿名内部类方式:
public static <R> R typeConver(Function<String, R> function) {
String str = "1235";
R result = function.apply(str);
return result;
}
@Test
public void testLambda4() {
Integer result = typeConver(new Function<String, Integer>() {
@Override
public Integer apply(String s) {
return Integer.valueOf(s);
}
});
System.out.println(result);
}
- Lambda方式:
public static <R> R typeConver(Function<String, R> function) {
String str = "1235";
R result = function.apply(str);
return result;
}
@Test
public void testLambda4() {
Integer result = typeConver((String s) -> {
return Integer.valueOf(s);
});
System.out.println(result);
}
范例五:
IntConsumer是一个接口,先使用匿名内部类的写法调用该方法;
- 匿名内部类方式:
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
@Test
public void testLambda5() {
foreachArr(new IntConsumer() {
@Override
public void accept(int value) {
System.out.println(value);
}
});
- Lambda方式:
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
@Test
public void testLambda5() {
foreachArr((int value) -> {
System.out.println(value);
});
}
省略规则
- 参数类型可以省略;
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
@Test
public void testLambda5() {
foreachArr((value) -> {
System.out.println(value);
});
}
- 方法体只有一句代码时大括号return和唯一一句代码的分号可以省略;
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
@Test
public void testLambda5() {
foreachArr((value) -> System.out.println(value));
}
- 方法只有一个参数时小括号可以省略;
public static void foreachArr(IntConsumer consumer) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int i : arr) {
consumer.accept(i);
}
}
@Test
public void testLambda5() {
foreachArr(value -> System.out.println(value));
}
- 以上这些规则都记不住也可以省略不记,可通过idea的replaceLambda表达式快速生成lambda表达式;
Stream 流
Stream将要处理的元素集合看作一种流,在流的过程中,借助Stream API对流中的元素进行操作。
Stream - 特性
Stream可以由数组或集合创建,对流的操作分为两种:
- 中间操作,每次返回一个新的流,可以有多个;
- 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。
Stream特性:
stream不存储数据,而是按照特定的规则对数据进行计算,一般会输出结果;
stream不会改变数据源,通常情况下会产生一个新的集合或一个值;
stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。
Stream - 创建方式
Stream创建方式有三种:
通过 java.util.Collection.stream() 方法用集合创建流;
使用java.util.Arrays.stream(T[] array)方法用数组创建流;
使用Stream的静态方法:of()、iterate()、generate()。
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* @author hos
* @Createdate 2022/3/21 14:40
*/
public class StreamCreateType {
public static void main(String[] args) {
/**
* Stream 流的创建有3种方式
* 1. Collection.stream()方法用集合创建
* 2. Arrays.stream(T[] array) 方法用数组创建
* 3. 使用Stream的静态方法:of()、iterate()、generate()
*/
//方式一: Collection.stream()方法用集合创建
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "6", "7", "8", "9");
// 创建一个顺序流
Stream<String> stream = list.stream();
// 创建一个并行流
Stream<String> stringStream = list.parallelStream();
List<String> collect = stringStream.collect(Collectors.toList());
//方式二: Arrays.stream(T[] array) 方法用数组创建
int[] array = {1, 2, 3, 4, 5};
IntStream stream1 = Arrays.stream(array);
System.out.println(stream1.max().getAsInt());
//方式三: 使用Stream的静态方法:of()、iterate()、generate()
Stream<Integer> intStream = Stream.of(1, 2, 3, 4, 5, 6);
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
// 0 3 6 9
stream2.forEach(System.out::println);
AtomicInteger m = new AtomicInteger(10);
Stream<Integer> stream3 = Stream.generate(()-> m.getAndIncrement()).limit(3);
//10 11 12
stream3.forEach(System.out::println);
}
}
Stream - 使用
中间操作
map
map,可以将一个流的元素按照一定的映射规则映射到另一个流中;
map,接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
filter
filter,对流中的元素进行条件过滤,符合过滤条件的才能继续留在流中;
filter,按照一定的规则校验流中的元素,将符合条件的元素提取到新的流中的操作。
distinct
distinct,去除流中的重复元素;
sorted
sorted(),自然排序,流中元素需实现Comparable接口;
sorted(Comparator com),Comparator排序器自定义排序。
limit
limit,可以设置流的最大长度,超出的部分将被抛弃;
skip
skip,跳过流中的前n个元素,返回剩下的元素;
flatMap
flatMap,接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流;
map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素。
终结操作
forEach
forEach方法,通过 lambda 表达式的方式遍历集合中的元素;
forEach,对流中的元素进行遍历操作,通过传入的参数去指定对遍历到的元素进行什么具体操作。
count
count,用来获取当前流中元素的个数;
max&min
max&min,可以用来或者流中的最值。
collect
collect,把当前流转换成一个集合;
collect,把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合;流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。
reduce
reduce,把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作;
reduce,对流中的数据按照你指定的计算方式计算出一个结果。
Lambda8 表达式的更多相关文章
- 【.net 深呼吸】细说CodeDom(2):表达式、语句
在上一篇文章中,老周厚着脸皮给大伙介绍了代码文档的基本结构,以及一些代码对象与CodeDom类型的对应关系. 在评论中老周看到有朋友提到了 Emit,那老周就顺便提一下.严格上说,Emit并不是针对代 ...
- 你知道C#中的Lambda表达式的演化过程吗?
那得从很久很久以前说起了,记得那个时候... 懵懂的记得从前有个叫委托的东西是那么的高深难懂. 委托的使用 例一: 什么是委托? 个人理解:用来传递方法的类型.(用来传递数字的类型有int.float ...
- 再讲IQueryable<T>,揭开表达式树的神秘面纱
接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...
- Linq表达式、Lambda表达式你更喜欢哪个?
什么是Linq表达式?什么是Lambda表达式? 如图: 由此可见Linq表达式和Lambda表达式并没有什么可比性. 那与Lambda表达式相关的整条语句称作什么呢?在微软并没有给出官方的命名,在& ...
- 背后的故事之 - 快乐的Lambda表达式(一)
快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...
- Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)
作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...
- SQL Server-表表达式基础回顾(二十四)
前言 从这一节开始我们开始进入表表达式章节的学习,Microsoft SQL Server支持4种类型的表表达式:派生表.公用表表达式(CTE).视图.内嵌表值函数(TVF).简短的内容,深入的理解, ...
- 立即执行函数表达式(IIFE)
原文地址:benalman.com/news/2010/11/immediately-invoked-function-expression/ 译者:nzbin 也许你还没有注意到,我是一个对术语比较 ...
- javascript:逆波兰式表示法计算表达式结果
逆波兰式表示法,是由栈做基础的表达式,举个例子: 5 1 2 + 4 * + 3 - 等价于 5 + ((1 + 2) * 4) - 3 原理:依次将5 1 2 压入栈中, 这时遇到了运算符 + ...
随机推荐
- 分布式 PostgreSQL - Citus 架构及概念
节点 Citus 是一种 PostgreSQL 扩展,它允许数据库服务器(称为节点)在"无共享(shared nothing)"架构中相互协调.这些节点形成一个集群,允许 Post ...
- Pycharm:设置完Anaconda后报错TypeError: an integer is required (got type bytes)
背景:安装了最新版本的Anaconda3.9后,在Pycharm中设置Python Interpreter为这个最新版本Anaconda文件下的python.exe后,控制台无法启动并报错TypeEr ...
- burpsuite中文乱码问题
无法显示中文 先查看网页编码 然后在修改编码为网页的编码一致并重启burpsuite即可(或者直接选第一项自动识别编码) 显示中文正常,但是无法匹配中文 找到了一处验证码漏洞,想用burpsuite的 ...
- redis缓存雪崩和缓存穿透
缓存雪崩:由于原有的缓存过期失效,新的缓存还没有缓存进来,有一只请求缓存请求不到,导致所有请求都跑去了数据库,导致数据库IO.内存和CPU眼里过大,甚至导致宕机,使得整个系统崩溃. 解决思路:1,采用 ...
- Flume介绍安装使用
APache Flume官网:http://flume.apache.org/releases/content/1.9.0/FlumeUserGuide.html#memory-channel 目录 ...
- 2022最新IntellJ IDEA诺依开发部署文档
前景提示 若伊是国内一款很好的开源项目,非常的便于学习,而且它是开源免费的,但是,它的开发部署文档实在是没法按照那个文档,快速高效的在本地搭建一套可以运行的项目,对于学习开发和使用实在是一大难题,为此 ...
- web Javascript360°全景实现
360 全景浏览是一种性价比很高的虚拟现实解决方案,给人一种全新的浏览体验,让你足不出户就能身临其境地感受到现场的环境.该技术被广泛地应用在房产.酒店.家居等领域. 下面我们使用三种方法讨论一个 36 ...
- LintCode 练习题
/** * 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数. 示例 1: 输入: 1->2->3->4->5->NULL, k = 2 输 ...
- python 生产数据表脚本
# -*- coding: utf-8 -*-import re"""建立相关表的字段从源表创建指定的MySQL建表脚本"""# 目标表名称 ...
- linux内存(二)高端内存
来此网址 https://ilinuxkernel.com/?p=1013 Linux内核地址映射模型x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访 ...