前面也有写一篇jdk8 + guava的博文,都是一些零碎的记录,感觉不是很好。
都说java8运行速度比之前的其他版本要快很多,这都要归功于Stream的概念,既然能那么快就从它与多线程的关系说起吧。
1、java 8 和多线程
在java8之前通过多线程来达到并行效果需要使用Thread API,syncharonized关键字,同时当线程访问并更新共享变量时,要是没有协调好线程之间的关系,可能就会出错。
而在java8中,会更多关注的是数据分块,而不是协调问题,所以基本上很少使用syncharonized,而是使用Stream的并行化方式来处理的。
如在两个CPU上刷选列表,可以先让一个CPU处理列表的前一半,另一个CPU处理后一半,即将大的数据流分块成小的数据流来处理,接着CPU会各自对自己的半个列表进行筛选,最后将两个结果合并到一个CPU上,在此基础上,当CPU越多,处理能力当然就会越强,既可以横向扩展。所以在处理时,基本上都会先将其转换成stream(parallelStream):
asList.stream().filter((String s) -> s.contains(“v")).collect(Collectors.toSet());
2、行为参数化
依旧使用上一个例子吧,行为参数化简单的来说就是把一个行为(即一段逻辑代码)封装起来,通过传递的方式将方法的行为参数化,即:上例中的(String s) -> s.contains(“v”)就表示一段行为,将其通过lambda方式作为参数传递至filter函数中,可以很大程度上简洁代码,且逻辑也很清晰。当lambda主体(即 -> 之后的内容)很多时,需要使用{}花括号将其包裹。
3、在java8中lambda当然是重点之一了
先看一下例子吧:
(Integer i) -> return “Study” + i;
(Strings) -> {“Study”;}
上面这两个其实都不是正确的lambda,第一个中必须使用花括号将这个控制流语句给包起来才可以,即(Integer i) ->{return “Study” + i};
至于第二个后面的部分是一个表达式,而不是语句,可以直接去掉花括号,或采用显式返回语句,即(Strings) -> {return “Study”;}
4、函数式接口
即只定义了一个抽象方法的接口(并不是之后一个方法,还可以有其他默认方法,或静态方法,仅仅是抽象方法只有一个而已)。java8中会大量的用到此接口,并且你可以看到一般像这种接口都会使用@FunctionalInterface来注解,简单的介绍几个最常用的吧:
1)java.util.function.Predicate<T>
它包含一个boolean test(T t);抽象方法,所以一般是在需要处理boolean问题时使用它:
stream.filter(vo -> vo.getAge()>25).distinct().skip(3).limit(6).collect(Collectors.toList());
2)java.util.function.Consumer<T>
void accept(T t); 即对给定的参数T执行操作,最常用的莫过于forEach了:
asList.forEach(System.out::print);
3)java.util.function.Function<T, R>
R apply(T t); 接受一个参数T,还需要返回一个类型R,所以一般为将某一个对象的信息映射输出。
str.chars().mapToObj(ch -> Character.valueOf((char)ch)).forEach(System.out::print);
函数式接口 | 函数描述符 | 原始类型特化 |
Predicate<T> | T -> boolean | IntPredicate, LongPredicate, DoublePredicate |
Consumer<T> | T -> void | IntConsumer, LongConsumer, DoubleConsumer |
Fuction<T,R> | T -> R |
IntFunction<R>, IntToDoubleFunction, IntToLongDouble
LongFunction<R>, LongToDoubleFunction, LongToIntFunction,
DoubleFunction<R>
ToIntFunction<T>, ToDoubleFunction<T>, ToLongFunction<T> |
Suppliter<T> | () -> T |
BooleanSupplier, IntSupplier, LongSuppliter, DoubleSuppliter |
UnaryOperator<T> | T -> T |
IntUnaryOperator, LongUnaryOperator, DoubleUnaryOperator |
BinaryOperator<T> | (T, T) -> T |
IntBinaryOperator, LongBinaryOperator, DoubleBinaryOperator |
BiPredicate<L, R> | (L, R) -> boolean | |
BiConsumer<T, U> | (T, U) -> void |
ObjIntConsumer<T>, ObjLongConsumer<T>, ObjDoubleConsumer<T> |
BiFunction<T, U, R> | (T, U) -> R |
ToIntBiFunction<T, U>, ToLongBiFunction<T, U>, ToDoubleBiFunction<T, U> |
5、在java8中,因为泛型只能绑定到引用类型,所以就会存在一个装箱 和 拆箱的问题:
装箱:将原始类型转换为引用类型(int -> Integer)。
拆箱:将引用类型转换为原始类型(Integer -> int)。
虽然有提供自动装箱过程,但由于装箱之后的存储值会需要更多的内存,且在搜索时也需要更多的内存来获取被包裹的原始值,在性能方面会消耗,所以提供了原始类型前缀的接口DoublePredicate、IntConsumer、LongBinaryOperator、IntFunction、ToIntFunction、IntToFunction等。
6、lambda与局部变量
要在lambda中使用局部变量,需要为变量添加final修饰符,guava中也存在。
对于局部变量的限制是因为:实例变量存储在队中,而局部变量存在在栈中,如果lambda可以直接访问局部变量,而lambda又在线程中使用,则会使用到lambda的线程,可能会在分配该变量的线程将这个变量收回之后才去访问该变量。因此当java访问自由局部变量时,实际上访问的是它的副本,而不是原始值。
7、lambda匿名类与闭包
所谓闭包,也就是一个函数的实例,只是可以将这个实例作为参数传递给另一个函数,并可以无限制的访问和修改其作用域之外的变量。而lambda虽然也可以作为参数传递给另一个函数,但它不能修改定义lambda的方法的局部变量,它和闭包还是有区别的。
8、lambda与方法引用,即使用::方式直接调用对应的方法
lambda中的方法引用也用的蛮多的,如下Math::random即Math.random()函数的引用:
Stream.generate(Math::random).limit(5);
构造函数的引用:
//无参构造函数
Supplier<UserVO> su = UserVO::new;
UserVO vo01 = su.get();
//一个参数的构造函数
Function<String, UserVO> fun = UserVO::new;
UserVO vo02 = fun.apply("xiaomi");
//两个参数的构造函数
BiFunction<String, Integer, UserVO> bifun = UserVO::new;
UserVO vo03 = bifun.apply("xiaomi", 4);
//多个参数的构造函数需要自己去自定义了
DataFunction<String, String, String, String, Record> data = Record::new;
Record record = data.apply("title", "content.....", "https://www.xiaomi.com", "search");
相关推荐
java记录随笔
简单记录了基于Ubuntu系统中搭建jdk1.8、mysql5.7、Tomcat9环境的方式,同时记录了修改数据库用户密码的过程
随笔记录java的一些基础知识,不停更新中.... 各个章节稍微有点乱,想起来的时候,可以查看一些知识点。 能简单帮助自己复习一下基础知识与原理性知识。
JavaThings-Java安全漫谈笔记相关《 Java安全漫谈》是我在写的一点Java学习相关的随笔,不是很严谨,也不是啥高科技。这个存储库主要是记录并整理一下,附加一些代码。Java安全漫谈目录 人口统计字节码:远程字节码...
现需要开发一款云随笔app,为了方便用户可以方便快捷的记录自己的日常生活、包括旅游、心事、学习笔记等等。用户填写的记录将会同步到云端以免数据的丢失,后继需要添加上传图片功能、云端数据的下拉
基于JAVA幼儿园家园共育平台设计与实现 开发语言 JavaWeb前端语言 开发工具:六年特雷利JIDEA ...童言稚语:每月记录一次幼儿有趣的话语,文字展示。 育儿头条:育儿新闻文章。管理员上传,可评论点赞
一杯82年的JAVA 大家好,我是练习时常两年半的JAVA练习生,爱好是 Coding、Technology、Reading、Learning 博客专用仓库,主要记录一些学习和实践的总结,感兴趣的朋友可以点个watch或star。 随笔 探索JAVA并发 从...
列表参考国光大佬的国光的安全随笔记录 安全技能 该技能表不用按顺序进行学习,但是比较高级的我会放最后面,因为我也不会,需要花时间慢慢加。 总结我这几年的一点经验:安全需要学习的技术太多了,特别是红队、...
mfc使用OLE读取Excel文件,工作中的随笔,小小记录下。借鉴了很多大神的博客,如有侵权,请联系删除,谢谢!
Java自动内存管理机制包含两部分:内存分配和内存回收,要想理解内存分配和回收的机制,则需要了解下Java内存区域(Java运行时数据区),这篇随笔将按照下面的线索进行逐步解析:1.Java运行时数据区2.对象“已死”的...
MiaoWu毕业设计-流浪猫收养系统过程随笔记录通知:1.用户关注用户2.关注的用户发帖3.帖子审核结果4.领养申请5.领养审核结果发帖:需发帖人有联系方式帖子详情页 数据获取顺序调整实现头像修改功能修改记录1.修改猫咪...
是我学习前端知识的随笔,记录着我的理解。 从2020年5月28日开始在GitHub上写笔记,之前一直是在自己电脑上写笔记。 希望能给大家带来帮助(目前还不是很完善,后面会一一补充) [toc] 目录 留着再链接到下面的内容...
- java categories : - 随笔 --- 更多信息配置,例如: --- title : "标题" date : " 2020-08-07 " description : 文章摘要 # 隐藏目录 hideToc : false #生成目录 enableToc : true # 博客展示目录 ...
.NET关于string转换的一个小Bug Regular Expressions 完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则表达式 delegate vs. event 我是谁?[C#] 表达式计算引擎...
转载的关于Osip的简介,以及基本的原理介绍等