Java8实战系列一
从java7到java8,最主要的变化可以总结为
□Lambda表达式
□ 方法引用
□流和默认方法
让我们通过一个小例子感受一下
情景 1 集合对象排序 (对list中的苹果按照重量排序)
- Collections.sort(list,new Comparator<Apple>(){
- public
int compare(Apple a1,Apple a2){ - return a1.getWeight()-a2.getWeight();
- }
- });
在java8里面,这种实现只需要一行很简短的代码
- list.sort(java.util.Comparator.comparing(Apple::getWeight))
这其中涉及到lambda表达式,接口中静态方法,方法引用等java8新特性,而且一看就明白其功能,给list排序,排序依据weight
Java多线程历程 java1.0 线程和锁------à java5 线程池和并发集合----------à java7 添加分支/合并(fork/join)--à java8 添加stream支持并发处理数据
在java8中加入Streams可以把 接口默认方法和把代码块传递给方法的简介方式(方法引用、lambda表达式)
把代码传递给方法 即是一种行为参数化思想,和函数式编程思想极为相近。
情景2 对目录文件过滤,筛选所有隐藏文件
- File [] hiddenFiles=new File(".").listFiles(new FileFilter(){
- public boolean accept(File file){
- return file.isHidden();
- }
- });
使用方法引用,直接将方法当做参数传递进去
- File [] hiddenFiles=new File(".").listFiles(File::isHidden)
既然对象File已经有了一个isHidden方法,我们不必再把它包含在啰嗦的匿名内部类里面过滤了。
与用对象引用(对象引用是用new创建的)类似,写下File::isHidden就创建一个方法引用,可以传递它
如可以写成这样
- FileFilter filter=File::isHidden;
- File [] isHiddenFiles2=new File(".").listFiles(filter);
从第一行代码可以看出,方法引用确实可以当做一个变量来使用
情景3 lambda传递条件代码 (筛选符合条件的苹果)
- public static List<Apple> filterGreenApple(List<Apple> list){
- List<Apple> result=new ArrayLst<>();
- for(Apple apple : list){
- if("green".equals(apple.getColor())){
- result.add(apple); //筛选颜色为绿色的苹果
- }
- }
- return result;
- }
- public static List<Apple> filterWeighterApple(List<Apple> list){
- List<Apple> result=new ArrayLst<>();
- for(Apple apple : list){
- if(apple.getWeight()>150){
- result.add(apple); //筛选重量大于150g的苹果
- }
- }
- return result;
- }
如果客户要筛选红苹果,筛选红且重量大于150g的苹果,…难道每次都要添加一个函数吗,而且这些函数除了条件筛选不一样,其他部分都是一样的。
首先我们可以把公用代码提出来
- public static List<Apple> filterApple(List<Apple> list){
- List<Apple> result=new ArrayList<>();
- for(Apple apple:list){
- if(....){ //苹果筛选条件
- result.add(apple);
- }
- }
- return result;
- }
- 进一步,我们可以把筛选条件传递进去
过滤函数可以改成这样 - public static List<Apple> filterApple(List<Apple> list,Predicate<Apple> p){
- List<Apple> result=new ArrayList<>();
- for(Apple apple:list){
- if(p.test(apple)){
- result.add(apple);
- }
- }
- return result;
- }
- Public interface Predicate<Apple>{
- Boolean test(Apple apple);
- }
即过滤函数有两个参数,一个时过滤的对象集合,一个时过滤的 条件对象(Predicate),而该条件对象应该有个可以返回Boolean的函数来确定是否符合条件(策略设计模式)
这样设计之后,把filterApple方法迭代集合的逻辑和要应用到集合中每个元素对象上的行为(谓词)区分开了。
比如要筛选出绿苹果
- public class GreenColorPredicate<Apple> implements Predicate<Apple>{
- public boolean test(Apple apple){
- if("green".equals(apple.getColor())){
- return true;
- }
- return false;
- }
- }
- GreenColorPredicate<Apple> greenPredicate=new GreenColorPredicate<>();
- filterApple(list,greenPredicate);
或者lambda表达式
- filterApple(list,(Apple apple)->"green".equals(apple.getColor()));
我们可以将上面的函数抽象化成泛型函数,这样就可以过滤香蕉,橘子等对象集合啦!!
行为参数化最大好处就是可以适应不断变化的需求。
总结:
1 行为参数化,就是一个方法接受多个不同的行为作为参数,在内部使用它们,完成不同行为的能力。
2 行为参数化可以让代码更好适应不同需求,减轻未来工作量。
3 传递代码,即将新行为作为参数传递给方法。可以用lambda表达式或者方法引用。
4 java api包含很多可以用不同行为进行参数化的方法,最常用就是排序,线程等。
Java8实战系列一的更多相关文章
- GitHub实战系列汇总篇
基础: 1.GitHub实战系列~1.环境部署+创建第一个文件 2015-12-9 http://www.cnblogs.com/dunitian/p/5034624.html 2.GitHub实战系 ...
- GitHub实战系列~1.环境部署+创建第一个文件 2015-12-9
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- GitHub实战系列~2.把本地项目提交到github中 2015-12-10
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- GitHub实战系列~3.提交github的时候过滤某些文件 2015-12-10
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- GitHub实战系列~4.把github里面的库克隆到指定目录+日常使用 2015-12-11
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- 05.GitHub实战系列~5.发布版本之分支操作+Tag讲解 2015-12-14
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- 07.GitHub实战系列~7.Git之VS2013团队开发(如果不想了解git命令直接学这篇即可)
GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...
- Spark入门实战系列--10.分布式内存文件系统Tachyon介绍及安装部署
[注]该系列文章以及使用到安装包/测试数据 可以在<倾情大奉送--Spark入门实战系列>获取 .Tachyon介绍 1.1 Tachyon简介 随着实时计算的需求日益增多,分布式内存计算 ...
- [.NET领域驱动设计实战系列]专题十一:.NET 领域驱动设计实战系列总结
一.引用 其实在去年本人已经看过很多关于领域驱动设计的书籍了,包括Microsoft .NET企业级应用框架设计.领域驱动设计C# 2008实现.领域驱动设计:软件核心复杂性应对之道.实现领域驱动设计 ...
随机推荐
- EClipse for PHP 中文乱码问题
UTF-8 格式的php,中文都是乱码. 如果此时在EClipse中输入中文会有 CP1252 错误( CP1252不支持xxxx ) 解决方法: windows->preferences-&g ...
- gdb调试5--工程项目的断点调试
之前说过断点调试,但是针对的是单文件的断点调试.在实际应用中,一个项目是多目录多文件的 参考资料:gdb debugger 目录结构: $ tree .├── gdbSomeFiles.cpp├── ...
- Win7任务栏合并
在“任务栏” -> "任务栏按钮" -> "始终合并.隐藏标签” 另外,如果想使时间显示详细,可消去“使用小图标”
- 批处理 ------ @、ECHO OFF、ECHO ON 的使用
1.在批处理文件中,如果命令前加@,表示这条命令不打印出来,只把结果打印出来,即@是关闭命令本身的回显 2.::在批处理中表示注释某一行 3.ECHO ON表示接下来的命令中(不包括本命令),执行命令 ...
- Django多域名配置之Django-hosts插件的使用
使用场景: Django中有两个app,如果通过域名来访问,可以使用www.domain.com/a.www.domain.com/b来访问.这样就显得有点LowB了.如果我想通过a.domain.c ...
- 牛客多校第十场-D- Rikka with Prefix Sum
链接:https://www.nowcoder.com/acm/contest/148/D来源:牛客网 Prefix Sum is a useful trick in data structure p ...
- Linux 4.10.8 根文件系统制作(二)---制作jiffs文件系统
一.制作jiffs文件系统 制作jffs2 文件系统需要用到 mkfs.jffs2工具. 执行命令: mkfs.jffs2 -n -s 0x800 -e 0x20000 --pad=0x800000 ...
- 数据库之MySQL存储过程
一.参考文献 https://www.oschina.net/translate/create-and-call-mysql-stored-procedure-database-sql-example ...
- HDU4685 Prince and Princess【强连通】
题意: 有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚,公主就比较悲惨, 跟谁结婚都行.然后输出王子可能的结婚对象,必须保证王子与任意这些对象中的一个结婚,都不会影 ...
- Android中的Service:Binder,Messenger,AIDL
http://blog.csdn.net/luoyanglizi/article/details/51594016 http://blog.csdn.net/luoyanglizi/article/d ...