Java8简明学习之Lambda表达式
函数式接口
就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口,函数式接口可以被隐式转换为lambda表达式。
之前已有的函数式接口:
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
java.io.FileFilter
1.8新增的函数式接口:
java.util.function包下
Predicate<T>——接收 T 并返回 boolean (常用)
Consumer<T>——接收 T,不返回值 (常用)
Function<T, R>——接收 T,返回 R (常用)
Supplier<T>——提供 T 对象(例如工厂),不接收值
UnaryOperator<T>——接收 T 对象,返回 T
BinaryOperator<T>——接收两个 T,返回 T
lambda表达式
lambda表达式的语法由参数列表、箭头符号 -> 和函数体组成。函数体既可以是一个表达式,也可以是一个语句块。
eg: (int x, int y) -> x + y (表达式)
eg:(Integer e) -> {
double sqrt = Math.sqrt(e);
double log = Math.log(e);
return sqrt + log;
} (语句块)
意义:传入参数x和y,返回x和y的和
表达式:表达式会被执行然后返回执行结果。
语句块:语句块中的语句会被依次执行,就像方法中的语句一样。
方法引用:
方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。
方法引用有很多种,它们的语法如下:
静态方法引用:ClassName::methodName
实例上的实例方法引用:instanceReference::methodName
超类上的实例方法引用:super::methodName
类型上的实例方法引用:ClassName::methodName
构造方法引用:Class::new
数组构造方法引用:TypeName[]::new
eg:
List<String> names5 = Arrays.asList("peter", "anna", "mike", "xenia");
names5.sort(String::compareTo);
System.out.println(names5);
public void testFun1() {
// comparing 是 Function<? super T, ? extends U> Function<T, R>——接收 T,返回 R
Person p1 = new Person();
p1.setName("hy");
p1.setAge(18);
Person p2 = new Person();
p2.setName("dax");
p2.setAge(19);
Person[] people = {p1, p2};
Comparator<Person> byName = Comparator.comparing(Person::getName);
Arrays.sort(people, byName);
for (Person person : people) {
System.out.println(person);
}
}
Stream
Stream与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念,Stream 是对集合(Collection)对象功能的增强。
eg:内部迭代和外部迭代
void innerOrOuter() {
List<Person> list = new ArrayList<>();
Person p1 = new Person();
p1.setName("hy");
p1.setAge(18); Person p2 = new Person();
p2.setName("dax");
p2.setAge(19); list.add(p1);
list.add(p2); for (Person p: list) {
p.setAge(20);
}
System.out.println(list); List<Person> list2 = new ArrayList<>();
Person p21 = new Person();
p21.setName("hy");
p21.setAge(18); Person p22 = new Person();
p22.setName("dax");
p22.setAge(19); list2.add(p21);
list2.add(p22); list2.stream().forEach(p->p.setAge(20));
System.out.println(list2);
}
Stream通用语法:
Stream的操作:
Intermediate(中间操作):
map (mapToInt, flatMap 等)、 filter、 distinct(去重)、 sorted(排序)、 peek(对某个元素做单独处理生成新的Stream)、
limit(取前N个元素)、 skip(丢弃前N个元素)、 parallel、 sequential、 unordered
Terminal(结束操作,非短路操作):
forEach、 forEachOrdered、 toArray、 reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator
Short-circuiting(结束操作,短路操作):
anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit
代表例子:
@Test
public void testNormal() {
// 1 线程
new Thread(()-> testThread()).start(); // 2 遍历集合
List<String> list = Arrays.asList("abd", "nba", "cba", "mctrady");
list.stream().forEach(n-> System.out.println(n));
list.forEach(n-> System.out.println(n)); // 3 map运用
List<Integer> listInt = Arrays.asList(123, 456, 789, 101);
listInt.stream().map(n->n*10).forEach(n-> System.out.println(n));
System.out.println(listInt.stream().mapToInt(n->n).sum());
System.out.println(listInt.stream().mapToInt(n->n).average().getAsDouble()); // 4 filter
List<Integer> listInt2 = Arrays.asList(123, 456, 789, 101);
listInt2.stream().filter(n->n>200).forEach(n-> System.out.println(n)); // 5 对每个元素应用函数
List<Integer> listInt3 = Arrays.asList(123, 456, 789, 101);
String str = listInt3.stream().map(n->n.toString()).collect(Collectors.joining(","));
System.out.println(str);
} private void testThread() {
System.out.println("线程操作");
}
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String a, String b) {
return b.compareTo(a);
}
});
System.out.println(names); List<String> names1 = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names1, (String a, String b) -> {
return b.compareTo(a);
});
System.out.println(names1); List<String> names2 = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names2, (String a, String b) -> b.compareTo(a));
System.out.println(names2); List<String> names3 = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names3, (a, b) -> b.compareTo(a));
System.out.println(names3); List<String> names4 = Arrays.asList("peter", "anna", "mike", "xenia");
Collections.sort(names4, String::compareTo);
System.out.println(names4); List<String> names5 = Arrays.asList("peter", "anna", "mike", "xenia");
names5.sort(String::compareTo);
System.out.println(names5); List<String> names6 = Arrays.asList("peter", "anna", "mike", "xenia");
// 反转
names6.sort(Comparator.comparing(String::toString).reversed());
System.out.println(names6);
public void testStream() throws ClassNotFoundException {
List<Person> list = new ArrayList<>();
Person p1 = new Person();
p1.setName("hy");
p1.setAge(18); Person p2 = new Person();
p2.setName("dax");
p2.setAge(19); list.add(p1);
list.add(p2); System.out.println(list); list.stream().forEach(p -> p.setAge(20)); System.out.println(list); list.stream().filter(s->s.getName().equals("hy")).forEach(p->p.setAge(21));
System.out.println(list); List<Person> listHy = list.stream().filter(s->s.getName().equals("hy") && s.getAge() == 21).collect(Collectors.toList());
System.out.println(listHy); int age = list.stream().mapToInt(s->s.getAge()).sum();
System.out.println("年龄总和:" + age); Optional<Person> firstHy = list.stream()
.filter(s -> s.getName().equals("hy"))
.findFirst();
Person person = firstHy.get();
System.out.println(person);
}
总结:
关于lambda和Stream的学习暂时先到这,如果日常用的就是1.8版本,这些就慢慢熟悉了,习惯了1.7以前面向对象编程的思维需要一些时间转换。而1.8里面lambda和Stream无疑是让Java更加的拥抱变化,在函数式编程里面也有了一些说话的位置。
参考:
http://zh.lucida.me/blog/java-8-lambdas-insideout-language-features/
https://blog.csdn.net/hanyingzhong/article/details/60965197
https://segmentfault.com/a/1190000008876546
Java8简明学习之Lambda表达式的更多相关文章
- Java8学习笔记----Lambda表达式 (转)
Java8学习笔记----Lambda表达式 天锦 2014-03-24 16:43:30 发表于:ATA之家 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人 ...
- Java8学习(3)- Lambda 表达式
猪脚:以下内容参考<Java 8 in Action> 本次学习内容: Lambda 基本模式 环绕执行模式 函数式接口,类型推断 方法引用 Lambda 复合 上一篇Java8学习(2) ...
- JAVA8学习——深入浅出Lambda表达式(学习过程)
JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...
- 【Java8新特性】你知道Java8为什么要引入Lambda表达式吗?
写在前面 这是一道真实的面试题,一个读者朋友出去面试,面试官竟然问他这样一个问题:你说说Java8中为什么引入Lambda表达式?引入Lambda表达式后有哪些好处呢?还好这个朋友对Java8早有准备 ...
- 【Java8新特性】Lambda表达式基础语法,都在这儿了!!
写在前面 前面积极响应读者的需求,写了两篇Java新特性的文章.有小伙伴留言说:感觉Lambda表达式很强大啊!一行代码就能够搞定那么多功能!我想学习下Lambda表达式的语法,可以吗?我的回答是:没 ...
- java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合
java8新特性: lambda表达式:直接获得某个list/array/对象里面的字段集合 比如,我有一张表: entity Category.java service CategoryServic ...
- java8学习之Lambda表达式继续探讨&Function接口详解
对于上次[http://www.cnblogs.com/webor2006/p/8186039.html]已经初步引入的Java8中Stream流的概念,其中使用了map的操作,它需要接受一个Func ...
- java8学习之Lambda表达式深入与流初步
Lambda表达式深入: 在上一次[http://www.cnblogs.com/webor2006/p/8135873.html]中介绍Lambda表达式的作用时,其中说到这点: 如标红处所说,既然 ...
- java8学习之Lambda表达式初步与函数式接口
对于Java8其实相比之前的的版本增加的内容是相当多的,其中有相当一大块的内容是关于Lambda表达式与Stream API,而这两部分是紧密结合而不能将其拆开来对待的,但是是可以单独使用的,所以从学 ...
随机推荐
- LOJ#3086. 「GXOI / GZOI2019」逼死强迫症(矩阵快速幂)
题面 传送门 题解 先考虑全都放\(1\times 2\)的方块的方案,设防\(i\)列的方案数为\(g_i\),容易推出\(g_i=g_{i-1}+g_{i-2}\),边界条件为\(g_0=g_1= ...
- Heap-451. Sort Characters By Frequency
Given a string, sort it in decreasing order based on the frequency of characters. Example 1: Input: ...
- css 题目笔记(本文收集了一些个人觉得比较有意思的css题目,欢迎大家给出自己的解答)
1.本文收集了一些个人觉得比较有意思的css题目,欢迎大家给出自己的解答 P标签的最大宽度不可以大于H2标签文字宽度的10% 这里应该是P标签的最大宽度由前面的匿名内联元素宽度(就是大字号文字宽度)决 ...
- 无头结点的单链表(C语言)
1.单链表: 在顺序表中,用一组地址连续的存储单元来一次存放线性表的结点,因此结点的逻辑顺序与物理顺序是一致的.但链表却不同,链表是用一组任意的存储单元来存放 线性表的结点,这组存储单元可以是连续的, ...
- WebDriverAPI(6)
在指定元素上方进行鼠标悬浮 测试网址 http://www.baidu.com Java语言版本实例 @Test public void roverOnElement() { driver.manag ...
- POJ 2336
#include <iostream> using namespace std; int main() { //freopen("acm.acm","r&qu ...
- IIS 8 配置错误
1) ProtocolException: The remote server returned an unexpected response: (405) Method Not Allowed Th ...
- Failed to create prime the NuGet cache
在centos 7上使用dotnet core时: dotnet core 安装环境在root下完成,并成功运行“hello world”程序.切换到其他账户使用dotnet命令时,报“Failed ...
- Spark源码的编译过程详细解读(各版本)(博主推荐)
不多说,直接上干货! 说在前面的话 重新试多几次.编译过程中会出现下载某个包的时间太久,这是由于连接网站的过程中会出现假死,按ctrl+c,重新运行编译命令. 如果出现缺少了某个文件的情况,则要 ...
- tomcat启动(Ⅶ)请求处理--Processor.process(SocketWrapper<S> socketWrapper)
tomcat启动(六)Catalina分析-StandardServer.start() 上一篇分析到:Http11NioProcessor.process(SocketWrapper<S> ...