java8简单入门

1、介绍

  本片文章会从一下几个知识点进行介绍:

  • 函数式接口 @FunctionalInterface
  • Lambda 表达式
  • 函数引用 Function Reference
  • Stream

  看了几篇关于 java8 入门的例子,其中引入了许多令人期待已久的特性(虽然我没有过这样的体会),但不管你的代码是普通青年款还是文艺青年款,你都可以从被 java8 的重新组织的代码看到她的简洁之处,不得不让我对这些新入贵圈(java圈)的小鲜肉做一些记录,以便我能很好的利用他们。

  最大的一个特点莫非就是引入了“函数式”编程这一个概念(都是剽窃的别的语言来的),还有那么多新奇的词语,比如“语法糖”“闭包”“显式|隐式函数”等这里我就不再一个一个去体会了,这里属于初次接触,先理解会用为主,细节的深入待后期慢慢琢磨。

 

2、函数式接口 -- @Functionnalinterface

  在翠花正式上代码示例之前,我们现来对这个函数式接口有个认识:

  1. 接口必须只有一个抽象方法;
  2. 接口可以有其他的默认(default)或者静态(static)方法;
  3. 接口默认继承了 Object 类,所以接口中不能覆盖了 Object 中的方法;

说明:该注解不是必须的,如果一个接口满足“函数式接口”特性,那么不加这个注解也没有影响,加上该注解能够更好的让编译器检查,如果不符合规范将会报编译错误。

  比如在 jdk8 中就对Comparator、Callable、Runnable等接口加上了该注解,下面两段代码的效果是一样的:

  

 1 public static void runThreadByLambda() {
 2     Runnable runnable = () -> System.out.println("这个是用拉姆达实现的线程");
 3     new Thread(runnable).start();
 4 }
 5 
 6 //---------------------------------------------------------------------------------
 7 public static void runThreadByInnerClass() {
 8     Runnable runnable = new Runnable() {
 9     @Override
10     public void run() {
11         System.out.println("这个是用内部类实现的线程");
12     }
13     };
14     new Thread(runnable).start();
15 }

 3、Lambda 表达式

  先用自己的语言来个 Lambda 下个定义:"一段带有输入参数的可执行语句块”。精确与否那是别人的事情,反正我是这么理解的(目前阶段是这样的)。

1 (Type1 param1, Type2 param2, ..., TypeN paramN) -> {
2   statment1;
3   statment2;
4   //.............
5   return statmentM;
6 }

  对应定义我们自然要给个例子

1 List<String> names = new ArrayList<>();
2 names.add("TaoBao");
3 names.add("ZhiFuBao");
4 List<String> lowercaseNames = names.stream().map((String name) -> {return name.toLowerCase();}).collect(Collectors.toList());

  这不就是将一个集合全部元素变为小写吗?和我以前用的循环代码繁简度不想上下,有什么好奇怪的!这位看管不要着急嘛,下面我来个他搓个背您再看看如何。

1 List<String> lowercaseNames = names.stream().map(name -> name.toLowerCase()).collect(Collectors.toList());
2 
3 //如果加入方法应用就是这样
4 List<String> lowercaseNames = names.stream().map(String::toLowerCase()).collect(Collectors.toList());

  简化规则如下:

  • 绝大部分情况下,编译器都可以从上下文推算出参数类型,因此可以省略
  • 当参数只有一个,可以省略小括号
  • 当表达式只包含一条语句时,可以省略大括号、returned和语句结尾的分号

  在 Lambda 眼中,外部的变量也是可以访问的,只是这个变量默认必须是 final ,即便你自己没有加上,编译器也会自动帮你加上,所以变大时内部访问外部变量必须是不可变的(只是引用不可变);还有一个东西就是 this ,this 在 lambda 指代的不是表达式生产的那个 SAM(Simple Abstract Method)对象,而是申明她的外部对象。

 

4、方法引用(Method reference)和构造器引用(Construct reference)

  • objectName::instanceMethod  
  • ClassName::staticMethod
    例子:System.out::println   等同于   x -> System.out.println(x)
               Math::max                等同于  (x,y) -> Math.max(x,y)
    前两种方法类似,等同于把 Lambda 表达式的参数当成实例方法或者静态方法的参数来调用,下面再来看看第三种情况
  • ClassName::instanceMethod
    例子:String.toLowerCase   等同于   x -> x.toLowerCase()
    等同于把 Lambda 表达式的第一个参数当成 实例方法的目标对象,其余参数当成该方法的参数来调用。
  • ClassName::new
    例子:BigDecimal::new    等同于   x -> new BigDecimal(x)
    等同于把 Lambda 的参数当成构造器的参数来调用。

5、Stream

  Stream 堪称 Lambda 的好基友,他们两个配合起来使用才能快快乐乐。

  • Stream 是元素的集合,这点让 Stream 看起来有些类似 iterator

  • 可以支持顺序和并行的对原 Stream 进行汇聚的操作
//Lists是Guava中的一个工具类
List<Integer> nums = Lists.newArrayList(1,null,3,4,null,6);

 

 

 

 

 

  5.1 创建 Stream

// of() 有两个,变长参数和单一参数
Stream<Integer> integerStream = Stream.of(1, 2, 3, 5);
Stream<String> stringStream = Stream.of("taobao");
// 匿名类的写法
Stream.generate(new Supplier<Double>() {@Overridepublic Double get() {return Math.random();}
});
// Lambda 写法
Stream.generate(() -> Math.random);
// 函数引用写法
Stream.generate(Math::random);
// generate() 生产一个无限长度的Stream
// iterate() 也是生产了一个无限长度的 Stream ,其是重复调用用户给定的种子值类获取元素,seed  f(seed)  f(f(seed))  ......
Stream.iterate(1, item -> item + 1).limit(10).forEach(System.out::println);

    除了上面 Stream 的静态工厂创建方法之外,就是下面的 Collection 接口的默认方法。

1 public interface Collection<E> extends Iterable<E> {
2     //其他方法省略
3     default Stream<E> stream() {
4         return StreamSupport.stream(spliterator(), false);
5     }
6 }

  5.2  转换 Stream

    顾名思义,就是通过一定的法则将原来的 Stream 转换成一个新的 Stream,下面列举一些常用的转换方法来加深理解,一图胜千言

 

 

 

从以上图中就可以看出来几个常用的 转换函数的功能,下面我们将大声的喊出我们的口号“在一起!”

1 List<Integer> nums = Lists.newArrayList(1,1,null,2,3,4,null,5,6,7,8,9,10);
2 System.out.println(“sum is:”+nums.stream().filter(num -> num != null).
3                distinct().mapToInt(num -> num * 2).
4                peek(System.out::println).skip(2).limit(4).sum());

  5.3 汇聚(Reduce) Stream

    汇聚,也称为折叠,接受一个元素序列为输入,反复使用某个合并操作,把序列中的元素合并成一个汇总的结果,下面会分两部分来介绍汇聚行为。

    5.3.1 可变汇聚

      把输入元素累计到一个可变的容器中,比如 Collection 或者 StringBuilder。

    5.3.2 其他汇聚

      除了可变汇聚之外的其余汇聚,一般不是通过反复修改某个可变对象,而是通过把前一次的汇聚结果当成下一次的入参,反复如此,比如reduce、count、allMatch

     

 

转载于:https://www.cnblogs.com/afanti558/p/7181867.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/252318.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩转带外触发的单目相机之一

背景&#xff1a;去年开始研究vins,但是只是用了普通的相机&#xff0c;然后将IMU和相机粘在一起&#xff0c;然后就是联合标定相机和IMU。VINS使用的相机是带有外触发的&#xff0c;还进行了相机和IMU的硬件时间同步。当时我特别想买个带外触发的相机&#xff0c;一直没找到资…

基于django的视频点播网站开发-step11-后台用户管理功能...

用户管理功能&#xff0c;包含用户添加、列表展示、编辑、删除四大功能。下面我们一一揭晓。 用户添加 我们先实现用户添加功能&#xff0c;我们现在urls.py下添加相关的路由 path(user_add/, views.UserAddView.as_view(), nameuser_add), path(user_list/, views.UserListVie…

分布式之数据库和缓存双写一致性方案解析

先做一个说明&#xff0c;从理论上来说&#xff0c;给缓存设置过期时间&#xff0c;是保证最终一致性的解决方案。这种方案下&#xff0c;我们可以对存入缓存的数据设置过期时间&#xff0c;所有的写操作以数据库为准&#xff0c;对缓存操作只是尽最大努力即可。也就是说如果数…

‘(‘:illegal token on right side of ‘::‘

背景&#xff1a;想整理升级一下代码&#xff0c;添加了两个类&#xff0c;再一编译代码&#xff0c;出现了好多这样的错误提示“(:illegal token on right side of ::”&#xff0c;我很纳闷这是啥问题&#xff0c;我就使用“注释法”来定位出错的位置&#xff0c;我发现把所有…

虹软免费人脸识别SDK注册指南

2019独角兽企业重金招聘Python工程师标准>>> 成为开发者三步完成账号的基本注册与认证&#xff1a; STEP1:点击注册虹软AI开放平台右上角注册选项&#xff0c;完成注册流程。 STEP2:首次使用&#xff0c;登录后进入开发者中心&#xff0c;点击账号管理完成企业或者个…

C++中的类加多线程代码修炼

背景&#xff1a;现在在做一个目标跟踪的项目&#xff0c;需要实时的从工业相机中获取图像&#xff0c;然后再跟踪图像上的目标物&#xff0c;由于起初为了测试跟踪算法&#xff0c;就把“从相机获取图像”和“跟踪处理”都放在了主线程中&#xff0c;在实际测试时&#xff0c;…

vue的鼠标移入和移出

vue的鼠标移入和移出 需求&#xff08;鼠标到预约二维码显示&#xff0c;预约添加背景色&#xff09; 实现 <!--html部分--> <ul class"person_list"> //五个li标签皆是循环渲染出来的<li class"item" v-for"(n,index) in 5">…

聊聊flink的MemoryPool

为什么80%的码农都做不了架构师&#xff1f;>>> 序 本文主要研究一下flink的MemoryPool MemoryPool flink-runtime_2.11-1.7.2-sources.jar!/org/apache/flink/runtime/memory/MemoryManager.java abstract static class MemoryPool {abstract int getNumberOfAvai…

表达式求值

表达式求值问题 ①问题描述 表达式是数据运算的基本形式。人们的书写习惯是中缀式&#xff0c;如&#xff1a;1122*(7-4)/3。中缀式的计算按运算符的优先级及括号优先的原则&#xff0c;相同级别从左到右进行计算。表达式还有后缀式&#xff08;如&#xff1a;22 7 4 - * 3 / 1…

C++中的类加多线程代码修炼之二

背景&#xff1a;在上一篇文章中 写到了我第一次使用C使用多个类多个线程进行编程&#xff0c;由于是第一接手“这么大一个工程”&#xff0c;所以还是要有个参照物的&#xff0c;由于我呢之前好几年一直在看的一个C代码工程就是ORB-SLAM了&#xff0c;这个工程使用C语言&#…

3-4 第三天 Generator生成器

Generator是ES6里面的新增规范&#xff0c;ES6其实就是ES2015。ES5、ES6、ES7这些术语大家上网一查就都明白了。JavaScript是一个范程&#xff0c;就是我们说的JS。ES就是ECMA Script&#xff0c;是JavaScript标准的书面说法。ES4、5、6、7其实是JS这门语言发展中的不同的版本。…

神奇的事情--长见识了

背景&#xff1a;我的这个工程里有多个命名空间&#xff0c;之所以是这样是因为&#xff0c;有一个跟踪算法他本身有几个namespace,然后我在他的基础上进行整合代码&#xff0c;将其作为一个功能接口&#xff0c;供其他函数调用&#xff0c;我在整合代码时&#xff0c;将我新加…

箭头函数的使用用法(一)

1 //箭头函数的一个好处是简化回调函数2 //箭头函数没有参数&#xff0c;就使用圆刮号代表参数部分&#xff1b;3 var f () >5;4 console.log(f());5 //两个参数的情况&#xff0c;代码块只有一条语句&#xff0c;可以省略{}6 var f (a,b)> console.log(ab);7 f(1,3);8…

LinkedList中查询(contains)和删除(remove)源码分析

一、contains源码分析 本文分析双向链表LinkedList的查询操作源码实现。jdk中源程序中&#xff0c;LinkedList的查询操作&#xff0c;通过contains(Object o)函数实现。具体见下面两部分程序&#xff1a;① public boolean contains(Object o) {return indexOf(o) ! -1; } ② p…

分块入门

我貌似和所有的数据结构都有些误会。。。。。。 在处理一些修改查询问题的时候&#xff0c;我们可以利用分治的思想&#xff0c;比如说把一个线性的数据不断分成一棵二叉树&#xff0c;也就是我们所说的线段树&#xff0c;这样我们就可以在logn的时限里做到修改和查询。同理我们…

开始使用gitlab

不得不说&#xff0c;我真不是一个合格的程序猿&#xff0c;工作马上两年了&#xff0c;github和gitlab用的一点也不熟练&#xff0c;每次兴致来了就搞几下&#xff0c;可是每次都浅尝辄止&#xff0c;不求甚解&#xff0c;时间一长&#xff0c;上一次练习的步骤就都记不起来了…

淘宝top平台调用接口响应时间优化

我的专栏地址&#xff1a;我的segmentfault,欢迎浏览 一、背景 调用top接口的响应时间长&#xff08;160ms左右&#xff09;&#xff0c;超时和连接异常频繁发生。导致消息组件消费工程的tps遇到瓶颈&#xff08;单实例单消息队列250tps&#xff09;&#xff0c;只能通过增加实…

win10上编译libharu库

背景&#xff1a; 最近的项目需要自动的生成pdf文件&#xff0c;我在网上查看相关的资料&#xff0c;发现目前比较流行的生成pdf文件的库有两个&#xff0c;一个是libpdf&#xff0c;另一个是libharu。libpdf个人使用时免费的但是商业使用就需要收费了&#xff0c;否则得到的p…

爬虫——正则表达式re模块

为什么要学习正则表达式 实际上爬虫一共就四个主要步骤&#xff1a; 明确目标&#xff1a;需清楚目标网站爬&#xff1a;将所有的目标网站的内容全部爬下来取&#xff1a;在爬下来的网站内容中去掉对我们没有用处的数据&#xff0c;只留取我们需要的数据处理数据&#xff1a;按…

深入Spring Boot:快速集成Dubbo + Hystrix

2019独角兽企业重金招聘Python工程师标准>>> 背景 Hystrix 旨在通过控制那些访问远程系统、服务和第三方库的节点&#xff0c;从而对延迟和故障提供更强大的容错能力。Hystrix具备拥有回退机制和断路器功能的线程和信号隔离&#xff0c;请求缓存和请求打包&#xff…