JAVA8给我带了什么——并流行和接口新功能
流,确定是笔者内心很向往的天堂,有他之后JAVA在处理数据就变更加的灵动。加上lambda表达不喜欢都不行。JAVA8也为流在提供另一个功能——并行流。即是有并行流,那么是不是也有顺序流。没有错。我前面操作的一般都是顺序流。在JAVA8里面并行流和顺序流是可以转变的。来看一个例子——笔者打印数字。

复制代码
1 package com.aomi;
2
3 import java.util.stream.LongStream;
4
5 public class Main {
6
7 public static void main(String[] args) {
8 // TODO Auto-generated method stub
9
10 LongStream.range(0, 10).forEach(i -> {
11 System.out.print(i + " ");
12 });
13 }
14
15 }
复制代码
LongStream.range这个方法是来获取数字的。这里表示获得0到10,但不含10 的数字。运行结果:

现在让我们把他换成并行来看看。

复制代码
1 package com.aomi;
2
3 import java.util.stream.LongStream;
4
5 public class Main {
6
7 public static void main(String[] args) {
8 // TODO Auto-generated method stub
9
10 LongStream.range(0, 10).parallel().forEach(i -> {
11 System.out.print(i + " ");
12 });
13 }
14
15 }
复制代码
运行结果:

俩个结果相比一下,我们就可以明显他们发生了变化。我们只是加一个parallel函数就发生好多的变化。笔者本来是要讲他们之间的性能比较的。不敢,因为笔者试好还有个例子。却发现有时候顺序流都比并行流来快。上面是顺序流转并行流。在来看一下相反的。

复制代码
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3
4 List datas = Arrays.asList(1,2,3,4,56);
5
6 datas.parallelStream().forEach(i -> {
7 System.out.print(i + " ");
8 });
9 }
复制代码
parallelStream函数就是用来建一个并行流的。运行结果:

转为顺序流

复制代码
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3
4 List datas = Arrays.asList(1,2,3,4,56);
5
6 datas.parallelStream().sequential().forEach(i -> {
7 System.out.print(i + " ");
8 });
9 }
复制代码
运行结果:

我们都知道流里面用到了JAVA7里面的分支和合并的框架来进行的。古代有一个词叫分而治之。把一个事情分为几个小事件。然面各自处理。所以了解代码里面是什么样子折分成小事件是非常重要的。他有俩个关键字Fork和Join。Fork方法你可以理解为拆分,并压入线程队列中。而Join就是合并的意思了。来笔者来写一个试。

复制代码
1 package com.aomi;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.concurrent.RecursiveTask;
6
7 public class DistinctCharForkJoin extends RecursiveTask> {
8
9 private List chars;
10
11 public DistinctCharForkJoin(List chars) {
12 this(chars, 0, chars.size());
13 }
14
15 public DistinctCharForkJoin(List chars, int start, int end) {
16
17 this.chars = chars.subList(start, end);
18 }
19
20 @Override
21 protected List compute() {
22 // TODO Auto-generated method stub
23 List tmpChars = new ArrayList();
24
25 // 判断不可以在拆分了
26 if (this.chars.size() < 3) {
27
28 for (Character character : chars) {
29 if (!tmpChars.contains(character))
30 tmpChars.add(character);
31 }
32
33 } else {// 表示可以在拆分。
34
35 int len = this.chars.size();
36
37 // 建立左边的小事件
38 DistinctCharForkJoin leftForkJoin = new DistinctCharForkJoin(chars, 0, len / 2);
39
40 leftForkJoin.fork();
41
42 // 建立右边的小事件
43 DistinctCharForkJoin rightForkJoin = new DistinctCharForkJoin(chars, len / 2, len);
44
45 rightForkJoin.fork();
46
47 List rChars = rightForkJoin.join();
48
49 List lChars = leftForkJoin.join();
50
51 // 俩个合并。
52 for (Character character : rChars) {
53 if (!tmpChars.contains(character))
54 tmpChars.add(character);
55 }
56
57 for (Character character : lChars) {
58 if (!tmpChars.contains(character))
59 tmpChars.add(character);
60 }
61
62 }
63
64 return tmpChars;
65 }
66
67 }
复制代码
Main:

复制代码
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3
4 List chars = Arrays.asList('a', 'b', 'c', 'd', 'b', 'a');
5
6 DistinctCharForkJoin task = new DistinctCharForkJoin("main", chars);
7
8 List resChars = new ForkJoinPool().invoke(task);
9
10 for (Character character : resChars) {
11
12 System.out.print(character +" ");
13 }
14 }
复制代码
运行结果:

你们一定很奇怪为什么笔者会讲到JAVA7带来的东西呢?JAVA8引入了一个新的接口——Spliterator接口。人称可分迭代器。如果你有心去看一个接口List的话,你可能会发现一个方法。如下

1 default Spliterator spliterator() {
2 return Spliterators.spliterator(this, Spliterator.ORDERED);
3 }
Spliterator接口:

1 public interface Spliterator {
2 boolean tryAdvance(Consumer<? super T> action);
3 Spliterator trySplit();
4 long estimateSize();
5 int characteristics();
6 }
讲JAVA7里面的分支/合并的目地就是为了理解Spliterator接口的作用。如下

tryAdvance:用于遍历当前的元素。如果还有的话,就返回true;
trySplit:用于拆分。如果当前不可以在拆分的话,就返回null;跟上面的compute方法很像。
estimateSize:表示还需要遍历的元素有多少。
characteristics:表示当前处理的数据是什么样子的。比如是否有序,每一元素是否为null。上面Spliterator接口的代码是笔者去掉大部分复制出来。这个值都在代码中。作用你们可以自己去看一下代码就是知道。
要注意Spliterator接口只是用去拆分任务的作用。JAVA8帮你做了很多拆分的功能。大部分你可以不用自己写。当然如果你想要自己动手。你只要实现这样子就可以了。如下

复制代码
1 package com.aomi;
2
3 import java.util.List;
4 import java.util.Spliterator;
5 import java.util.function.Consumer;
6
7 public class DistinctCharSpliterator implements Spliterator {
8
9 private List chars;
10 private int index = 0;
11
12 public DistinctCharSpliterator(List chars) {
13 this.chars = chars;
14 }
15
16 public DistinctCharSpliterator(List chars, int start, int end) {
17 this.chars = chars.subList(start, end);
18 }
19
20 @Override
21 public boolean tryAdvance(Consumer<? super Character> action) {
22 // TODO Auto-generated method stub
23 action.accept(this.chars.get(index++));
24 return index < this.chars.size();
25 }
26
27 @Override
28 public Spliterator trySplit() {
29 // TODO Auto-generated method stub
30 int difLen = this.chars.size() - index;
31
32 // 判断不可以在拆分了
33 if (difLen < 3) {
34 return null;
35 } else {// 表示可以在拆分。
36
37
38 DistinctCharSpliterator spliterator = new DistinctCharSpliterator(chars.subList(index, index + 2));
39
40 index = index + 2;
41
42 return spliterator;
43
44 }
45 }
46
47 @Override
48 public long estimateSize() {
49 // TODO Auto-generated method stub
50 return this.chars.size() - index;
51 }
52
53 @Override
54 public int characteristics() {
55 // TODO Auto-generated method stub
56 // 有序 元素不空 遍历过程不能删除,和修改 增加
57 return ORDERED + NONNULL + IMMUTABLE;
58 }
59
60 }
复制代码
Main:

复制代码
1 public static void main(String[] args) {
2 // TODO Auto-generated method stub
3
4 List chars = Arrays.asList('a', 'b', 'c', 'd', 'b', 'a');
5
6 DistinctCharSpliterator distinctCharSpliterator = new DistinctCharSpliterator(chars);
7
8 Stream stream = StreamSupport.stream(distinctCharSpliterator, true);
9
10 stream.distinct().forEach((Character ch) -> {
11
12 System.out.print(ch+" ");
13 });
14
15 }
复制代码
运行结果:

上面的例子有一点烂。但是大家可以复制做一下继点去看看他的执行过程。就可以看出很多东西来。主要是理解这个原理就可以了。
流的并行功能并没有让笔者有多心动。真正让笔者感觉不错的要属于JAVA8对接口的升级。什么意思?笔者不清楚有多少个人写个框架或是读过框架源码,一般框架里面都会用到一些面向接口的编程模式。那个或多或少会有这样子感觉。一但项目发布出去,这个时候你想要修改接口。比如在接口里面增加一个新的功能方法。这样子时候你就不得不考虑一下外面有多少个人在实现你现在框架的接口。因为你增加一个接口的新方法。别人也要跟着实现,不然的一定会报错或是运行时候报错。不管哪一种都是设计者不想看到的。
JAVA8现在可以让你定义接口的默认方法。什么思意呢?让笔得写一个例子。

Base接口:

1 package com.aomi;
2
3 public interface Base {
4 void call();
5 }
BaseA类:

复制代码
1 package com.aomi;
2
3 public class BaseA implements Base {
4
5 @Override
6 public void call() {
7
8 }
9
10 }
复制代码
Main:

复制代码
1 package com.aomi;
2
3 public class Main {
4
5 public static void main(String[] args) {
6 // TODO Auto-generated method stub
7
8 Base baseA = new BaseA();
9
10 baseA.call();
11 }
12 }
复制代码
上面的代码没有什么特别的。现在笔者在加一个方法。看一个他会不会有问题。如下

base类:

1 package com.aomi;
2
3 public interface Base {
4 void call();
5 void call2();
6 }
结果:

看到吧。BaseA类马上就报错。现在笔者在加上一个默认的方法会什么呢?

复制代码
package com.aomi;

public interface Base {

void call();default void call2() {System.out.println("default call2");
}

}
复制代码
Main修改一下吧。

复制代码
1 package com.aomi;
2
3 public class Main {
4
5 public static void main(String[] args) {
6 // TODO Auto-generated method stub
7
8 Base baseA = new BaseA();
9
10 baseA.call2();
11 }
12 }
复制代码
运行结果:

上面的代码。笔者在BaseA类里面并没有实现call2的方法。显然现在的功能对我们写框架的人来写太棒了。在也不用担心增加一个接方法而去考虑有多少个人用这个接口了。
那么问题来了。我们在写代码的过程中,一定会遇到方法相同的情况吧。这个时候JAVA8提供了三个标准来确定用哪一个。

类或父类的方法优先级高于接口默认的方法。
如果上面不行的话,谁拥有最具体的实现的话,就用谁。
如果都不能确定的情况下,就必须显性的调用。来指定他要调哪一个。
举例子。A和B都是接口。其中B继承了A。同时C实现了A和B。这个时候调用C会是什么样子。
A:

public interface A {

default void call() {System.out.println("A call");
}

}
B:

public interface B extends A {

default void call() {System.out.println("B call");
}

}
C:

public class C implements A, B {

}
D:

复制代码
public static void main(String[] args) {

    // TODO Auto-generated method stubC c = new C();c.call();}

复制代码
运行结果:

上面A和B都是接口。他们有call方法。其中关键是B继承了。说明B拥有A的一切方法。那么是不是说B就是最具体实现的。如果你们只用第一个标准的话,那是肯定不行的。
还是简单一点,我们把B继承A的这个关系去掉,在来看看。

不好意思好像报错了。所以只能苦一下了。显性调用。

复制代码
package com.aomi;

public class C implements B, A {

public void call() {B.super.call();
}

}
复制代码
当然除了上面之外,你还是可以定义静态方法和常量。这个时候有人就会说他不是跟抽象类很像吗?是很像。可是不一样子。抽象类是不是可以实例一个字段。但是接口却不行。还有抽像类你只能单继承。接口就可以多继承了。
原文地址https://www.cnblogs.com/hayasi/p/10639994.html

JAVA8给我带了什么——并流行和接口新功能相关推荐

  1. Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(计算器简单功能)

    Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(计算器简单功能) 导读 动态演示调用python库的tkinter带你进入GUI世界(计算器简单功能) 目录 ...

  2. 一文带你全面认识Excel催化剂系列功能

    2018年1月1日决定打造一款Excel插件,取名为Excel催化剂,历时半年的时间,在努力打造出和传统插件有功能差异化的基础上,让大家可以真正得到一些有价值非鸡肋的功能,对开发什么样的功能也构思了许 ...

  3. java8 streams_Java SE 8新功能介绍:使用Streams API处理集合

    java8 streams 使用Java SE 8 Streams的代码更干净,易读且功能强大..... 在" Java SE 8新功能导览"系列的这篇文章中,我们将深入解释并探索 ...

  4. 注重移动端体验,新商云带你开启社交电商新时代

    近几年,电商经济发展极为迅速,电商系统在为用户提供越来越多选择的同时,也迎来了新的电商时代-社交电商.这种新型模式依托于微信小程序,搭建专属微商城,因为微商城的搭建基于互联网具有较高的覆盖率,传播率, ...

  5. Android图片加载框架最全解析(七),实现带进度的Glide图片加载功能

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/78357251 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭 ...

  6. 三分钟带你看懂HDMI接口的PCB设计

    三分钟带你看懂HDMI接口的PCB设计 本文主要讲解的是HDMI的设计,包括作用和运用的总结,希望大家看了以后能轻松的应对各种HDMI方案的PCB设计. 一.什么是HDMI? 高清晰度多媒体接口(英文 ...

  7. 手把手教你带货直播源码实现直播功能,不依赖第三方SDK

    手把手教你带货直播源码实现直播功能,不依赖第三方SDK 先上图: 推流的手机 拉流的网页和VL播放器 拉流的手机客户端 下面开始实现手机直播功能 1.首先你要准备一份编译好的ffmpeg+x264库, ...

  8. 随身wifi,360wifi,猎豹wifi一边去,不花钱windows自带开启虚拟wifi,随身wifi功能

    是不是感觉买一个随身wifi,360wifi,钱也不多对吧!其实我们自己也可以开启.压根就不用花这钱了. 如果你说:我不买买买,我又猎豹wifi. 好吧!一边去,当我没说.其实猎豹wifi,也是类似如 ...

  9. python keyshot_带你快速了解KeyShot 6中的新功能

    原标题:带你快速了解KeyShot 6中的新功能 经常有朋友问起好用吗?KeyShot在版本完善的同时增加了强大的新功能,加快了渲染速度和创建高质量的视觉效果,体验一种完整工作流与更快的照明功能和扩展 ...

最新文章

  1. R语言ggplot2可视化图例放置在图像底部(bottom)并分两行显示实战
  2. POJ 3180 Tarjan
  3. stm32官方例程在哪找_STM32开发学习资料合集
  4. 通信网络基础期末复习-第三章-网络的时延分析
  5. Java算法-奇怪的分式
  6. 【Linux】一步一步学Linux——command命令(226)
  7. 计算机二级考试科目python难吗_计算机二级python考试难吗
  8. python爬虫百度图片_python实现爬取百度图片的方法示例
  9. 测试管理和自动化测试工具篇
  10. excel删除重复数据保留一条_Excel怎么快速查找和删除重复数据
  11. 基于数据挖掘技术的客户关系管理系统设计与实现
  12. 用Java实现修改头像
  13. 2022长三角数学建模A题:学在长三角
  14. web页面性能优化及SEO优化
  15. 【游戏逆向】浅谈某平台调试软件检测分析
  16. 【时间序列分析】03. 谱密度
  17. 黑马《linux基础编程》学习笔记(从16到20)
  18. 什么是拖延症 ----- 时间管理:终结拖延症小技巧之高效利用时间
  19. Web全栈开发基础(小白入门版本)
  20. 广义表的长度,深度及复制广义表的算法

热门文章

  1. SharedObject实例.
  2. 关于 IE 模态对话框的两个问题
  3. 使用Cobbler安装多版本操作系统
  4. SEO优化之——html页面相关总结
  5. 使用Spring Task轻松完成定时任务
  6. 阿里Q1财报:云计算付费用户首超100万
  7. PgSQL · 最佳实践 · 从 MaxCompute (ODPS) 迁移数据到 HybridDB
  8. 我再也不-或许永远不-用zend studio-受够了!
  9. Linux 循环与变量
  10. 射手科技公开课第一辑 『项目管理和代码规范』