`

Java8 随笔记录(一)

    博客分类:
  • jdk8
阅读更多

前面也有写一篇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记录随笔

    java记录随笔

    ubuntu搭建Java项目运行环境-随笔记录.rar

    简单记录了基于Ubuntu系统中搭建jdk1.8、mysql5.7、Tomcat9环境的方式,同时记录了修改数据库用户密码的过程

    java的基础性小结与笔记

    随笔记录java的一些基础知识,不停更新中.... 各个章节稍微有点乱,想起来的时候,可以查看一些知识点。 能简单帮助自己复习一下基础知识与原理性知识。

    JavaThings:共享与Java相关的东西-Java安全漫谈笔记相关内容

    JavaThings-Java安全漫谈笔记相关《 Java安全漫谈》是我在写的一点Java学习相关的随笔,不是很严谨,也不是啥高科技。这个存储库主要是记录并整理一下,附加一些代码。Java安全漫谈目录 人口统计字节码:远程字节码...

    Android App_云随笔课程设计

    现需要开发一款云随笔app,为了方便用户可以方便快捷的记录自己的日常生活、包括旅游、心事、学习笔记等等。用户填写的记录将会同步到云端以免数据的丢失,后继需要添加上传图片功能、云端数据的下拉

    基于JAVA的幼儿园家园共育平台设计与实现-需求.zip

    基于JAVA幼儿园家园共育平台设计与实现 开发语言 JavaWeb前端语言  开发工具:六年特雷利JIDEA ...童言稚语:每月记录一次幼儿有趣的话语,文字展示。 育儿头条:育儿新闻文章。管理员上传,可评论点赞

    java源码博客-source:个人博客,记录一些学习和实践的总结

    一杯82年的JAVA 大家好,我是练习时常两年半的JAVA练习生,爱好是 Coding、Technology、Reading、Learning 博客专用仓库,主要记录一些学习和实践的总结,感兴趣的朋友可以点个watch或star。 随笔 探索JAVA并发 从...

    java版植物大战僵尸源码-Todo:定个计划好好学习

    列表参考国光大佬的国光的安全随笔记录 安全技能 该技能表不用按顺序进行学习,但是比较高级的我会放最后面,因为我也不会,需要花时间慢慢加。 总结我这几年的一点经验:安全需要学习的技术太多了,特别是红队、...

    MFC读取Execl文件.docx

    mfc使用OLE读取Excel文件,工作中的随笔,小小记录下。借鉴了很多大神的博客,如有侵权,请联系删除,谢谢!

    JVM自动内存管理机制

    Java自动内存管理机制包含两部分:内存分配和内存回收,要想理解内存分配和回收的机制,则需要了解下Java内存区域(Java运行时数据区),这篇随笔将按照下面的线索进行逐步解析:1.Java运行时数据区2.对象“已死”的...

    MiaoWu:毕业设计-流浪猫收养系统

    MiaoWu毕业设计-流浪猫收养系统过程随笔记录通知:1.用户关注用户2.关注的用户发帖3.帖子审核结果4.领养申请5.领养审核结果发帖:需发帖人有联系方式帖子详情页 数据获取顺序调整实现头像修改功能修改记录1.修改猫咪...

    Front-end-study-notes:顾名思义,前端学习笔记。里面包括的不仅仅是前端。扎根基础,不做浮水之萍

    是我学习前端知识的随笔,记录着我的理解。 从2020年5月28日开始在GitHub上写笔记,之前一直是在自己电脑上写笔记。 希望能给大家带来帮助(目前还不是很完善,后面会一一补充) [toc] 目录 留着再链接到下面的内容...

    eternidad33.github.io:不定期更新的Hugo博客,主要记录技术文章,现已经部署在Gitee和GitHub上,主题是Zzo

    - java categories : - 随笔 --- 更多信息配置,例如: --- title : "标题" date : " 2020-08-07 " description : 文章摘要 # 隐藏目录 hideToc : false #生成目录 enableToc : true # 博客展示目录 ...

    asp.net知识库

    .NET关于string转换的一个小Bug Regular Expressions 完整的在.net后台执行javascript脚本集合 ASP.NET 中的正则表达式 常用的匹配正则表达式和实例 经典正则表达式 delegate vs. event 我是谁?[C#] 表达式计算引擎...

    oSIP开发者手册

    转载的关于Osip的简介,以及基本的原理介绍等

Global site tag (gtag.js) - Google Analytics