【Java】Java8的Lambda入门记录
简化定义匿名实现类
匿名实现类的传统方式
创建一个线程,需要实现Runnable接口,并实现public void run()方法,用传统的方式是这样的:
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("hello world");
}
}).start();
}
无参数、单语句方法体
用lambda可以简化成这样:
Runnable r = () -> System.out.print("hello world");
new Thread(r).start();
所以也可以这样:
public static void main(String[] args) {
new Thread(() -> System.out.println("hello world")).start();
}
所以,没参数、单语句的是这样的:
public class NoParameter {
public static void main(String[] args) {
MyInterface myInterface = () -> System.out.println("Hello World");
myInterface.methodA();
}
public interface MyInterface {
public void methodA();
}
}
无参数、多语句方法体
当然实现方法中有多条语句的情况下,应该是这样的:
public static void main(String[] args) {
new Thread(() -> {
System.out.println("1");
System.out.println("2");
}).start();
}
多参数、多语句方法体
多参数、多语句的是这样的:
public class MoreParameterMoreStatement {
public static void main(String[] args) {
MyInterface myInterface = (x, y) -> {
System.out.println("1st parameter : " + x);
System.out.println("2nd parameter : " + y);
};
myInterface.methodA(1, 5);
}
public interface MyInterface {
public void methodA(Integer x, Integer y);
}
}
流,Stream
这里的流,并非Java IO的流,是简化处理Java Collection的流。
过滤条件
public static void main(String[] args) {
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
Stream<String> stream = list.stream();
Predicate<String> predicate = s -> s != null && s.equals("1"); // 断言,Predicate。入参对象,出参boolean,用于判别一个对象
System.out.println("count -> " + stream.filter(predicate).count()); // 过滤并统计
}
简写:
/**
* 过滤
*/
@Test
public void predicateTestx1() {
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
List<String> resultList = list.stream().filter(s -> s != null && s.equals("1")).collect(Collectors.toList());
this.logger.info("resultList -> " + resultList);
}
Predicate有一个抽象方法:boolean test(T t);,入参是对象,出参是布尔值。
filter方法会调用test方法:
@Override
public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
Objects.requireNonNull(predicate);
return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
StreamOpFlag.NOT_SIZED) {
@Override
Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(P_OUT u) {
if (predicate.test(u)) // 调用test()的逻辑
downstream.accept(u); // 加入下沉集合
}
};
}
};
}
转换为不同类型的集合
public static void main(String[] args) {
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
Stream<String> stream = list.stream();
Function<String, Integer> function = i -> Integer.valueOf(i); // Function<T, R>,转换成不同的类型
List<Integer> resultList = stream.map(function).collect(Collectors.toList());
System.out.println(resultList);
}
简写:
/**
* 转换类型
*/
@Test
public void functionTestx1() {
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
List<Integer> resultList = list.stream().map(i -> Integer.valueOf(i)).collect(Collectors.toList());
this.logger.info("resultList -> " + resultList);
}
合并多个集合
public static void main(String[] args) {
List<String> list1 = Arrays.asList(new String[] {"1", "2", "3"});
List<String> list2 = Arrays.asList(new String[] {"4", "5", "6"});
Function<List<String>, Stream<String>> function = list -> list.stream(); // List<String>转换为Stream<String>
List<String> allList = Stream.of(list1, list2).flatMap(function).collect(Collectors.toList()); // 合并多个集合
System.out.println(allList);
}
简写:
/**
* 转换类型
*/
@Test
public void mergeTestx1() {
List<String> list1 = Arrays.asList(new String[] {"1", "2", "3"});
List<String> list2 = Arrays.asList(new String[] {"4", "5", "6"});
// 这个不是我想要的结果
/*
List<List<String>> resultList1 = Stream.of(list1, list2).collect(Collectors.toList());
this.logger.info("resultList1 -> " + resultList1);
*/
List<String> resultList2 = Stream.of(list1, list2).flatMap(i -> i.stream()).collect(Collectors.toList());
this.logger.info("resultList2 -> " + resultList2);
}
获取集合最大、最小值
public static void main(String[] args) {
List<String> list = Arrays.asList(new String[] {"1", "2", "3"});
String max = list.stream().max(String::compareTo).get(); // 使用compareTo
String min = list.stream().min((x, y) -> x.compareTo(y)).get(); // 手动调用compareTo
System.out.println("max -> " + max);
System.out.println("min -> " + min);
}
分解操作,Reduce
/**
* 计算1-10总和
*/
public static void main(String[] args) throws Exception {
List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); // 声明集合
BinaryOperator<Integer> binaryOperator = (x, y) -> {
int temp = x + y;
logger.info("temp sum -> {}", temp);
return temp;
};
int sum = list.stream().reduce(binaryOperator).get();
logger.info("sum -> {}", sum);
}
日志:
2017-09-17 21:53:33.529 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 3
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 6
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 10
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 15
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 21
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 28
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 36
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 45
2017-09-17 21:53:33.535 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 55
2017-09-17 21:53:33.536 [main] INFO c.n.exercise.stream.ReduceExercise - sum -> 55
并行操作
这里例子的关键在于parallel()设置了并行处理,具体对比与reduce的日志。
/**
* 计算1-10总和
*/
public static void main(String[] args) throws Exception {
List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); // 声明集合
BinaryOperator<Integer> binaryOperator = (x, y) -> {
int temp = x + y;
logger.info("temp sum -> {}", temp);
return temp;
};
int sum = list.stream().parallel().reduce(binaryOperator).get();
logger.info("sum -> {}", sum);
}
日志:
2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-2] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 19
2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-1] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 9
2017-09-17 21:48:32.018 [main] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 13
2017-09-17 21:48:32.018 [ForkJoinPool.commonPool-worker-3] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 3
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-2] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 27
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 12
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-2] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 40
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 15
2017-09-17 21:48:32.023 [ForkJoinPool.commonPool-worker-1] INFO c.n.exercise.stream.ReduceExercise - temp sum -> 55
2017-09-17 21:48:32.024 [main] INFO c.n.exercise.stream.ReduceExercise - sum -> 55
两个集合的操作工具类:减去、交集、并集
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.assertj.core.util.Lists;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CollectionUtils {
private static Logger logger = LoggerFactory.getLogger(CollectionUtils.class);
/**
* 计算在list1存在,而在list2不存在的记录的集合
*/
public static <T> List<T> subtract(List<T> list1, List<T> list2) {
// 转换为Set
Set<T> set = list2.stream().collect(Collectors.toSet());
// 计算在list1存在,而在list2不存在的记录的集合
List<T> resultList = list1.stream().filter(i -> !set.contains(i)).collect(Collectors.toList());
return resultList;
}
/**
* 计算交集,在list1存在,并且在list2也存在的记录的集合
*/
public static <T> List<T> intersect(List<T> list1, List<T> list2) {
// 转换为Set
Set<T> set = list2.stream().collect(Collectors.toSet());
// 计算在list1存在,而在list2不存在的记录的集合
List<T> resultList = list1.stream().filter(i -> set.contains(i)).collect(Collectors.toList());
return resultList;
}
/**
* 计算并集,在list1和list2的记录合并,并且去重的集合
*/
public static <T> List<T> union(List<T> list1, List<T> list2) {
Set<T> set = Stream.of(list1, list2).flatMap(i -> i.stream()).collect(Collectors.toSet());
List<T> resultList = set.stream().collect(Collectors.toList());
return resultList;
}
@Test
public void subtractTest() {
List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
List<Integer> list2 = Lists.newArrayList(1, 5);
List<Integer> resultList = CollectionUtils.subtract(list1, list2);
this.logger.info("list1 -> {}", list1);
this.logger.info("resultList -> {}", resultList);
}
@Test
public void intersectTest() {
List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
List<Integer> list2 = Lists.newArrayList(1, 5);
List<Integer> resultList = CollectionUtils.intersect(list1, list2);
this.logger.info("list1 -> {}", list1);
this.logger.info("resultList -> {}", resultList);
}
@Test
public void unionTest() {
List<Integer> list1 = Lists.newArrayList(1, 2, 3, 4, 5);
List<Integer> list2 = Lists.newArrayList(1, 5, 6);
List<Integer> resultList = CollectionUtils.union(list1, list2);
this.logger.info("list1 -> {}", list1);
this.logger.info("resultList -> {}", resultList);
}
}
【Java】Java8的Lambda入门记录的更多相关文章
- Lambda 表达式,Java中应用Lambda 表达式
一.Lambda 表达式 简单来说,编程中提到的 lambda 表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数. 链接:知乎 先举一个普通的 Python 例 ...
- [一] java8 函数式编程入门 什么是函数式编程 函数接口概念 流和收集器基本概念
本文是针对于java8引入函数式编程概念以及stream流相关的一些简单介绍 什么是函数式编程? java程序员第一反应可能会理解成类的成员方法一类的东西 此处并不是这个含义,更接近是数学上的 ...
- java8新特性-入门摘要
本文是针对java8做的入门摘要笔录,详细分析可参见如下原文. 原文地址 http://www.javacodegeeks.com/2013/02/java-8-from-permgen-to-met ...
- Java8一Lambda与函数式接口
关于Lambda表示在工作学习中会经常用到,但并没有全面的去了解.在这里做一个较为详细的记录供以后学习查阅.主要参考Java 8 Lambda 表达式 引言 Java8之前,我们在使用Runnale创 ...
- Java8中Lambda表达式的10个例子
Java8中Lambda表达式的10个例子 例1 用Lambda表达式实现Runnable接口 //Before Java 8: new Thread(new Runnable() { @Overri ...
- Java程序员快速入门Go语言
这篇文章帮助Java程序员快速入门Go语言. 转载至 开源中国社区. http://www.oschina.net 本文将以一个有代表性的例子为开始,以此让Java程序员对Go语言有个初步认识,随后将 ...
- 十分钟学会Java8的lambda表达式和Stream API
01:前言一直在用JDK8 ,却从未用过Stream,为了对数组或集合进行一些排序.过滤或数据处理,只会写for循环或者foreach,这就是我曾经的一个写照. 刚开始写写是打基础,但写的多了,各种乏 ...
- Java8之lambda表达式
一.什么是lambda表达式? Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码 ...
- Java 8里面lambda的最佳实践
Java 8已经推出一段时间了,越来越多开发人员选择升级JDK,这条热门动弹里面看出,JDK7最多,其次是6和8,这是好事! 在8 里面Lambda是最火的主题,不仅仅是因为语法的改变,更重要的是带来 ...
随机推荐
- linux学习笔记 ftp命令
ftp server with sites et up for downloaing files sometimes provides an anonymous ftp account 数据传输 ft ...
- Touch事件详解及区别,触屏滑动距离计算
移动端有四个关于触摸的事件,分别是touchstart.touchmove.touchend.touchcancel(比较少用), 它们的触发顺序是touchstart-->touchmove- ...
- 数学——Euler方法求解微分方程详解(python3)
算法的数学描述图解 实例 用Euler算法求解初值问题 \[ \frac{dy}{dx}=y+\frac{2x}{y^2}\] 初始条件\(y(0)=1\),自变量的取值范围\(x \in [0, 2 ...
- Python3基础-代码阅读系列—优惠码生成
代码展示 import random # 生成200组长度为8的优惠码,字典集是数字加字母 def generate_key(number=200, length=8): char_set = &qu ...
- Scrapy基础(四)————Scrapy的使用Pycharm进行Debuge设置
好比Django的Debuge 与前端进行交互时的方便,但是Scrapy 不自带,所以我们写一个main文件来debuge 作用:通过cmd 命令启动爬虫 #-*-coding:utf-8 -*- # ...
- LeetCode(509. 斐波那数)
问题描述: 斐波那契数,通常用 F(n) 表示,形成的序列称为斐波那契数列.该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就是: F(0) = 0, F(1) = 1 F(N) ...
- 【DWM1000】 code 解密6一TAG 状态机第一步
我们前面分析过,不论ANCHOR 还是TAG,前面变量的初始化基本都是一样的,只是状态机必须明确区分不同的设备类型.我们从开始看TAG.由于初始化TAG的 testAppState一样初始化为TA_I ...
- 潭州课堂25班:Ph201805201 django 项目 第五课 静态页面转为模板 (课堂笔记)
一.分析静态页面 1.静态vs动态 条目 静态页面 动态页面 网站内容 固定不变 经常变动 浏览器加载速度 更快(无需向服务器发起请求) 更慢 改变网站内容 很难(修改或者创建新的html页面) ...
- MySql 5.7.20版本免安装版配置过程
下载地址为: https://dev.mysql.com/downloads/mysql/ 最下面根据自己的操作系统选择合适的型号 下载完以后解压缩到自定义的路径.这里注意的是路径中不要存在中文. 解 ...
- BZOJ2368 : Modern Art Plagiarism 树同构
枚举$T_1$的树根,然后DP,设$f[i][j]$表示$T_1$的子树$i$是否存在包括i的连通子树与$T_2$的子树$j$同构. 若$j$是叶子,那么显然可以. 若$deg_i<deg_j$ ...