原文:http://www.techempower.com/blog/2013/03/26/everything-about-java-8/
1.接口增强

(1)接口可以定义static方法

java.util.Comparator:

public static <T extends Comparable<? super T>> Comparator<T> naturalOrder() {

    return (Comparator<T>)Comparators.NaturalOrderComparator.INSTANCE;

}

(2)接口可以有default方法

java.lang.Iterable:

public default void forEach(Consumer<? super T> action) {

    Objects.requireNonNull(action);

    for (T t : this) {

        action.accept(t);

    }

}

default方法不能够override:toString()、equals()、hashCode()方法。

An interface cannot provide a default implementation for any of the methods of the Object class。

接口不能够提供Object类里面的方法的default实现。

ps:接口看上去越来越像抽象类了。

2.Functional接口

一个接口只定义了一个abstract方法,这个接口就是“functional接口”,比如:java.lang.Runnable。

“functional接口”中可以定义default方法

新引入@FunctionalInterface来标记

3.Lambdas表达式

functional接口可以用Lambdas来实例化。

(int x, int y) -> { return x + y; } :两个入参,一个返回值

(x, y) -> x + y:两个入参,一个返回值,自动推断类型

x -> x * x:一个入参,一个返回值,自动推断类型

() -> x:没有入参,一个返回值

x -> { System.out.println(x); }:一个入参,没有返回值,自动推断类型

String::valueOf static方法引用

Object::toString  非static方法引用

x::toString   Capturing method reference

ArrayList::new  构造函数引用

以下是等价的:

方法引用        
等价的Lambdas表达式

String::valueOf
x -> String.valueOf(x)

Object::toString
x -> x.toString()

x::toString
() -> x.toString()

ArrayList::new
() -> new ArrayList<>()

ps:看到String::valueOf这种引用方式,不仅让人想起了C++。

如果Lambdas表达式和“functional接口”外形相似,二者就可以兼容:

Comparator<String> c = (a, b) -> Integer.compare(a.length(),b.length());

Comparator类的compare()方法接收两个String的入参,返回一个int,跟右边的Lambdas表达式兼容。

所谓的外形相似就是说:入参、返回、checked异常。

Runnable r = () -> { System.out.println("Running!"); }也是ok的。

Capturing 与 non-capturing lambdas

如果一个Lambdas表达式访问了{}范围以外的非static的变量或者对象,那就是个Capturing Lambdas表达式:

int x = 5;

return y -> x + y;

Lambdas表达式captures了变量x,x必须得是“final等效”的:要么是final的,要么没有被修改过。

是否是Capturing Lambdas与性能有关,non-capturing的性能更高,non-capturing只需要被evaluated一次,只有一个instance,

但是,每次遇到Capturing lambdas都会evaluated,类似于匿名内部类的实例化。

3.新添加包:java.util.function

这个包下面添加了很多functional接口:

Function<T, R> - take a T as input, return an R as ouput

Predicate<T> - take a T as input, return a boolean as output

Consumer<T> - take a T as input, perform some action and don't return anything

Supplier<T> - with nothing as input, return a T

BinaryOperator<T> - take two T's as input, return one T as output, useful for "reduce" operations

新添加了对应基本数据类型的功能函数类,比如:

IntConsumer接收int,无返回,主要是为了性能的原因,避免自动拆装箱。

4.新添加包:java.util.stream

java.util.stream这个包主要是为了support functional-style operations on streams of value。

常见的获取stream的方式是从Collection获取:

Stream<T> stream = collection.stream();

一个stream就类似于是一个Iterator,只能遍历一次,当然stream也可能是无穷的。

stream可能是串行的也可能是并行的。

stream能做什么呢?

int sumOfWeights = blocks.stream().filter(b -> b.getColor() == RED)

                                  .mapToInt(b -> b.getWeight())

                                  .sum();

以上使用了简单类型的stream,sum()方法只有在简单类型的stream上才有。

stream提供了api用来转换value,或者是对结果做一些操作,对stream的操作可以是“中间操作”也可能是“终止操作”。

中间操作:会保持stream处于打开的状态,并允许进一步的操作,上例中的filter()和mapToInt()就是中间操作,返回的还是当前的stream,允许更多的链式操作。

终止操作:必须是stream上的最后一个操作,一旦被调用,stream就被消费掉,而且不能再使用了。

一般来说,对stream的处理包含三个步骤:

(1)从源处获取stream

(2)做一个或多个中间操作

(3)做一个终止操作

Stream可以是有状态(Stateful)的。

stream是可以短路操作(Short-circuiting)的,比如在处理无穷的stream的时候就需要提前停止。

stream的api方法介绍:

中间操作:

filter:排除掉所有不满足预定条件的元素

map :使用Function对元素做一对一的转换

flatMap :把一个元素映射成0个或者多个元素

distinct :根据equals方法,排除掉所有的重复元素,这是个stateful的操作。

sorted :让元素有序,stateful

limit :让后续的操作只能看到最多limit个元素,stateful并且short-circuiting

substream :让后续的操作只能看到stream的一部分。

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "Dave");

List<String> filteredNames = names.stream().filter(e -> e.length() >= 4).collect(Collectors.toList());

for (String name : filteredNames) {

    System.out.println(name);  //Alice Charlie Dave

}

终止操作:

forEach :对stream的每一个元素做一些处理

toArray :把元素导出到数组里面

reduce :使用BinaryOperator,把多个stream组合成一个

collect :把元素导出到某个容器里面,比如:collection或者map

min,max ,count ,

anyMatch :是否至少一个匹配的元素,short-circuiting。

allMatch :是否所有的元素都匹配,short-circuiting。

noneMatch :是否所有的元素都不匹配,short-circuiting。

findFirst :找到第一个匹配的元素,hort-circuiting。

findAny :找到任何一个匹配的元素,hort-circuiting。

中间操作是延迟(lazy)的。只有终止操作才会触发对stream的处理。在终止操作开始的时候,无论有多少中间操作, 

the elements are then consumed in (usually, but not quite always) a single pass.所有的元素都是进行一次性处理,

有些Stateful操作(sorted(),distinct())可能会进行第二次处理。

有专门针对基本类型的stream:IntStream,LongStream,DoubleStream

List<String> strings = Arrays.asList("hello", "java", "");

Object[] list = strings.stream()                  // Stream<String>

        .mapToInt(String::length)                 // IntStream

        .mapToLong(x -> Long.valueOf(x))          // LongStream

        .mapToDouble(x -> x * 2.0)                // DoubleStream

        .boxed()                                  // Stream<Double>

        .toArray();

System.out.println(java.util.Arrays.toString(list));//[10.0, 8.0, 0.0]

5.泛型类型推断增强

java7里面:

foo(Utility.<Type>bar());

Utility.<Type>foo().bar();

但是java8里面:

foo(Utility.bar());

Utility.foo().bar();

6.新引入java.time包

LocalDateTime:日期+时间

LocalDate:日期

LocalTime:时间

Instant:类似于java.util.Date

DateTimeFormatter:与字符串的转化

与老的api转化:

Date.toInstant()

Date.from(Instant)

Calendar.toInstant()

7.新添加了Collections API

Iterable.forEach(Consumer)

Iterator.forEachRemaining(Consumer)

Collection.removeIf(Predicate)

Collection.spliterator()

Collection.stream()

Collection.parallelStream()

List.sort(Comparator)

List.replaceAll(UnaryOperator)

Map.forEach(BiConsumer)

Map.replaceAll(BiFunction)

Map.putIfAbsent(K, V)

Map.remove(Object, Object)

Map.replace(K, V, V)

Map.replace(K, V)

Map.computeIfAbsent(K, Function)

Map.computeIfPresent(K, BiFunction)

Map.compute(K, BiFunction)

Map.merge(K, V, BiFunction)

Map.getOrDefault(Object, V)

List<String> strings = Arrays.asList("a", "b", "c");

// Index strings by length:

Map<Integer, List<String>> map = new HashMap<>();

for (String s : strings) {

    map.computeIfAbsent(s.length(),key -> new ArrayList<String>()).add(s);

}

System.out.println(map);//{1=[a, b, c]}

把stram里面的元素放到colection或者map里面:

List<String> strings = Arrays.asList("a", "b", "c","hello","world");

// Although in this case the stream API may be a better choice:

Map<Integer, List<String>> map = strings.stream().collect(Collectors.groupingBy(String::length));

System.out.println(map);//{1=[a, b, c], 5=[hello, world]}

8.新添加了Concurrency API

ConcurrentHashMap被完全重写

9.新添加了Concurrency API

10.反射和注解增强

注解可以加在泛型参数上: List<@Nullable String>

11.Nashorn JavaScript Engine

12.其他的一些api:

Base64

StringJoiner

Objects.isNull(Object) 

Objects.nonNull(Object) 

ThreadLocal<List<String>> strings = ThreadLocal.withInital(ArrayList::new);

people.sort(

    Comparator.comparing(Person::getLastName)

        .thenComparing(Person::getFirstName)

        .thenComparing(

            Person::getEmailAddress,

            Comparator.nullsLast()

                .thenComparing(String.CASE_INSENSITIVE_ORDER)));

总之一句话,加入了lambda表达式的java越来越像动态语言了,源码也越来越看不懂了,估计得好好的适应一段时间了。

jdk8预览的更多相关文章

  1. Kafka Eagle 3.0.1功能预览

    1.概述 最近有同学留言,关于Kafka Eagle的一些使用问题.今天笔者就为大家来详细介绍Kafka Eagle 3.0.1的功能以及使用方法. 2.内容 在3.0.1版本中,EFAK优化了分布式 ...

  2. Word/Excel 在线预览

    前言 近日项目中做到一个功能,需要上传附件后能够在线预览.之前也没做过这类似的,于是乎就查找了相关资料,.net实现Office文件预览大概有这几种方式: ① 使用Microsoft的Office组件 ...

  3. 预览github里面的网页或dome

    1.问题所在: 之前把项目提交到github都可以在路径前面加上http://htmlpreview.github.io/?来预览demo,最近发现这种方式预览的时候加载不出来css,js(原因不详) ...

  4. IE8/9 本地预览上传图片

    本地预览的意思是,在选择图片之后先不上传到服务器,而是由一个<img>标签来预览本地的图片,非 IE8/9 浏览器可以从<input type="file"/&g ...

  5. JS图片上传预览插件制作(兼容到IE6)

    其实,图片预览功能非常地常见.很意外,之前遇到上传图片的时候都不需要预览,也一直没有去实现过.现在手上的项目又需要有图片预览功能,所以就动手做了一个小插件.在此分享一下思路. 一.实现图片预览的一些方 ...

  6. [干货来袭]MSSQL Server on Linux预览版安装教程(先帮大家踩坑)

    前言 昨天晚上微软爸爸开了全国开发者大会,会上的内容,我就不多说了,园子里面很多.. 我们唐总裁在今年曾今透漏过SQL Server love Linux,果不其然,这次开发者大会上就推出了MSSQL ...

  7. 微软发布 Windows Server 2016 预览版第三版,开发者要重点关注Nano Server

    微软已经发布 Windows Server 2016 和 System Center 2016 第三个技术预览版,已经提供下载.Windows Server 2016 技术预览版第三版也是首个包括了容 ...

  8. Visual Studio Code预览版Ver 0.3.0试用体验

    当你开始阅读这篇文章时,请先不要把Visual Studio Code和.net.Windows联想到一起,因为VS Code是一个跨平台,支持30多种语言的开箱代码编辑器.不管你是.Net.Java ...

  9. UploadFile控件,提交图片后,页面预览显示刚刚提交的图片

    最近在用asp.net来写一个新闻系统后台,然后由于不用用网上的flash插件来上传图片什么的,我就用asp.net的控件来写,但是控件总归有一些用的不够灵活的地方.这次测试提出,文章在修改的时候,需 ...

随机推荐

  1. libeXosip2(1-1) -- How-To initialize libeXosip2.

    How-To initialize libeXosip2. The eXtented eXosip stack Initialize eXosip and prepare transport laye ...

  2. 关于Tcp三次握手的思考

    一.为什么不能使两次握手,两次握手就应该可以保证线路的畅通? 1) 只能建立一个方向的连接,称为半连接 记住TCP是全双工的. A向B发出请求,同时收到B的确认,这时只有A.B知道A到B的连接成功了. ...

  3. poj 3579 Median (二分搜索之查找第k大的值)

    Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numb ...

  4. textChanged(*)重点

    # -*- coding: cp936 -*- import sys from PyQt4 import QtCore, QtGui class MyDialog(QtGui.QDialog): de ...

  5. 关于VS2008中的targetver.h文件

    targerver.h文件的作用: 定义程序运行的环境,如限制程序只能在XP下运行,限制程序在只能在Vin7下运行 或限制程序只能在XP以上系统运行,或限制程序只能在Server2003以上系统运行. ...

  6. EffectiveC#03--用委托表示回调,用事件定义对外接口

    1.回调的场景:我给了儿子一个任务且他可以报告状态来(重复的)打断我.而我在等待他完成任务的每一个部份时不用阻塞我自己的进程.他可以在有重要(或者事件)状态报告时,可以定时的打断我,或者向我询求帮助 ...

  7. 如何排版 微信公众号「代码块」之 MarkEditor

    前段时间写过一篇文章 如何排版微信公众号「代码块」,讲的是如何使用浏览器插件 Markdown Here 来排版代码块.虽然用 Markdown Here 排版出来的样式还不错,但存在一个问题,就是代 ...

  8. HTML基础知识笔记(一)

    HTML定义 HTML指的是超文本标记语言 HTML不是编程语言,而是标记语言 标记语言是一套标记标签 HTML是用标记标签来描述网页   HTML标签1 <html></html& ...

  9. SqlServer存储过程传入Table参数

    今天是周日,刚好有空闲时间整理一下这些天工作业务中遇到的问题. 有时候我们有这样一个需求,就是在后台中传过来一个IList<类>的泛型集合数据,该集合是某个类的实例集合体,然后将该集合中的 ...

  10. Code Complete阅读笔记(一)

    代码大全也读了好几个月了,一开始读中文版,到现在慢慢尝试着读原版,确实感受到了"每天进步一点点"的魅力.遗憾的是没有从一开始就做阅读记录,总有不能尽兴和思路不清之感.确实,就像项目 ...