java8 新特性
来源:互联网 发布:java怎么调试错误 编辑:程序博客网 时间:2024/04/27 05:42
1.简介
毫无疑问,Java 8是自Java 5(2004年)发布以来Java语言最大的一次版本升级,如果不学习,你会怀疑自己面前的代码是不是Java。Java 8带来了很多的新特性,比如编译器、类库、开发工具和JVM(Java虚拟机),但最最主要的还是函数式编程。接下来将会结合代码去展示Java 8的新特性。
下面主要介绍Java 8的最显著特性:
接口增强
Lambda编程
函数式接口
Stream
Annotations
接口增强
Java 8允许我们在方法前使用default
关键字在接口中加入一个具体的方法。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在实现Formula接口的时候只需实现calculate
即可(当然也可以重写sqrt
方法)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
关键字default
定义的方法不可以直接通过接口类名调用
- 1
- 2
必须通过实例化的接口对象调用。接口在加入这个特性后非常像抽象类,也就是说我们可以在接口中实现模板模式。
与此同时,Java 8还允许我们在接口中添加一个静态方法,如上例的positive
方法。
Lambda 表达式
Java 8中最大的特性应该就是加入了函数式编程,那么函数式编程语言是什么?函数式编程语言的核心是它以处理数据的方式处理代码
我们看一个Java的简单例子
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
我们经常像这个代码一样写一些匿名内部类。在Java 8你可以通过Lambda来代替这种编程
- 1
- 2
Lambda的基本形式是()->
,->
左面是入参,可以为空,->
右面是具体的执行,可以写多行,但需要使用{}
,这样我们就把一段代码写入了函数的参数
我们以后就可以这样开一个Thread了
- 1
- 2
- 3
Lambda函数的作用域
既然我们上面说到了Lambda表达式和匿名内部类很像,那么使用参数的作用域也是如此,在Lambda中可以使用类的成员函数或者static变量,有点稍稍不同的是,如果使用方法中的变量在内部类中必须使用定义为final
的变量,Lambda没有明确要求变量必须使用final定义,但该变量不能更改(其实只是不需要final
的final
),所以下面最后一行代码会导致出错。
- 1
- 2
- 3
- 4
- 5
函数式接口
函数式接口的目的是为了使Lambda表达式更好的融入Java,那我们先看看什么是函数式接口,如果一个接口只包含一个抽象的方法,那么该接口成为函数式接口,同时提供一个新的注解@FunctionalInterface
,这个注解不是必须的,如果满足条件不加@FunctionalInterface
也会被虚拟机翻译为函数式接口,若增加@FunctionalInterface
将会增加编译时的检查,如果接口不满足将会在编译时报错。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
default
方法不能使用Lambda表达式。
同时Java 8自带了很多函数式接口,例如Comparator
和Runnable
,同时还加入了很多很好用的函数式接口
Predicates
Predicate提供一个单参数返回值为Boolean的函数式接口,返回值定义为其泛型
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
Functions
Function
Suppliers
Suppliers提供一个无参的方法,返回值为定义的泛型
- 1
- 2
- 3
Consumers
而Consumers则是提供一个一个参数的void函数
- 1
- 2
- 3
Comparators
在以往的Java中这个借口还是很常见的,现在的Comparator增加了很多的default和static方法。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
Optionals
Optionals不是函数式接口但是是一个很实用的final类,Optional主要针对函数时而返回值时而返回null的时候,比如我们在Map.get
的时候或者调用网络接口都是这样的使用场景
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
方法或构造函数引用
方法引用
Java 8引入::
关键字使得我们对类中的方法和构造函数的使用增加了一种方式。上面的例子可以这么改写
- 1
- 2
- 3
- 4
上面我们通过::
引用了Integer的静态工厂方法valueOf
。那么非静态方法的使用是如何呢?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
构造方法引用
我们来看构造方法如何使用
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
再创建一个工厂类用于创建
- 1
- 2
- 3
- 4
我们不需要实现该工厂,只需要传递引用
- 1
- 2
- 3
而且我们不需要指定参数,Java编译器会根据构造函数的方法签名去匹配正确的构造函数。
Stream
Steam适用在集合数据处理,Java 8在java.util.Collection
中的List
和Set
(Map
并不直接提供)。
Steam存在两组重要的概念中间操作和终止操作和并行和串行
中间操作和终止操作是指根据对Stream流操作的结果而言,如果是中间操作那么将会返回Stream,以便接下来继续操作,而终止操作则是返回最终的操作结果,不能再对Stream操作。可以看到,有了Stream我们可以轻松对集合进行一系列的复杂操作,而且我们只需要写一行代码。类似于pipeline功能。
串行和并行
先创建一个List
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Collections
在Java 8提供了创建Stream的方法,Collection.stream()
-串行流和Collection.parallelStream()
-并行流
中间操作和终止操作
- Filter
顾名思义,Filter可以为我们提供过滤功能,这是一个中间操作,我们可以设置我们需要的过滤规则。
- ForEach
还是顾名思义,也就是循环遍历Stream中的元素,显然这是一个终止操作。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- Sorted
Sorted是一个中间操作,可以接受Comparator
参数,如果不传参将会默认使用字典顺序。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
同时中间操作都不会改变原集合,也就是Java 8为中间操作重新分配了内存。
- 1
- 2
- 3
并行的优势
上面的例子我们都是串行
,我们通过一个例子来看一下并行操作能带来的性能提升
- 1
- 2
- 3
- 4
- 5
- 6
- 7
串行操作
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
并行操作
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
当然,具体性能的提升跟你的电脑性能有关,但是很明显并行
给我们带来的不仅仅是性能的提升,如果我们在Java 8之前操作,我们必然要考虑多线程执行时候的同步
问题吧,就拿上例来说,我们如果使用3个线程操作,那么三个线程需要从集合中取不同的数据,然后对中间结果sum
的使用的时候我们需要保证操作的原子性
。现在Java 8只需要一个方法,迅速摆脱烦恼啊!
Map
Map虽然没有直接提供Stream
方法,但是我们可以创建Map中key
,value
,entrySet
的Stream
同时Map提供了很多非常使用的方法
- forEach
顾名思义是用来遍历的
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- putIfAbsent & computeIfPresent
顾名思义第一个如果该key
为null
则插入。第二个是如果存在就计算
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- getOrDefault
顾名思义,根据key
获取,如果不存在则使用默认值
- 1
- 2
Annotations
注解在Java 8是可以重复的。只需要使用注解@Repeatable
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
注释 Annot 被 @Repeatable( Annots.class ) 注解。Annots 只是一个容器,它包含 Annot 数组, 编译器尽力向程序员隐藏它的存在。通过这样的方式,Test 类可以被 Annot 注解两次。重复注释的类型可以通过 getAnnotationsByType() 方法来返回。
Java 8剩余的特性
除了上述Java 8带来的很显著的变化。Java 8当然还有一些其他的特性:
- Date
API 如果你被Date类恶心过,那么你一定很期待Java 8给你带来的全新感受
- JVM
元空间(Metaspace):一个新的内存空间的诞生
- Concurrency
Java 8
concurrentForkJoinPool
类添加了新的方法来支持通用线程池操作。同时Java 8还添加了新的java.util.concurrent.locks.StampedLock
类,用于支持基于容量的锁——该锁有三个模型用于支持读写操作(可以把这个锁当做是java.util.concurrent.locks.ReadWriteLock的替代者)
- java8 新特性
- java8新特性 ---译
- Java8新特性教程
- Java8新特性学习
- JAVA8新特性
- Java8新特性详解
- JAVA8的新特性
- java8 新特性
- java8新特性
- java8 新特性
- JAVA8新特性一览
- Java8 新特性学习
- Java8新特性 Stream
- java8新特性
- java8新特性
- java8新特性
- java8新特性学习
- JAVA8新特性
- POJ 1006 Biorhythms
- Android.Application
- Navicat连接阿里云Ubuntu的mysql
- 欢迎使用CSDN-markdown编辑器
- 写给立志做码农的大学生
- java8 新特性
- leetcode 405. Convert a Number to Hexadecimal 十进制转化十六进制
- nginx 公用一个tomcat,配置不同的域名
- 女博士养成记2——挣钱养梦
- Linux进程间通信(1)
- 【UE4 全局光照明】虚幻引擎学习之路:渲染模块之全局光照明 by UWA侑虎科技
- 正向代理与反向代理
- 通过什么可以让SQL语句更加快速的获得结果
- C语言学习的第六天(续)