http://www.oracle.com/technetwork/java/javase/8-whats-new-2157071.html
https://www.oschina.net/translate/the-adventurous-developers-guide-to-jvm-languages?lang=chs&page=2#
1.lambda:也可称为闭包, 允许把函数作为一个方法的参数。Lambda 表达式免去了使用匿名方法的麻烦。
lambda 表达式只能引用 final 或 final 局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。
Runnable r = ()-> System.out.println("hello lambda!");
Comparator<Integer> cmp = (x, y) -> (x < y) ? -1 : ((x > y) ? 1 : 0);
interface Action{ void run(String para);}
public void execute(Action action){action,run();}
execute((String s)->Ssytem.out.println(s)) —— SAM模式
2.在接口中,可以直接添加静态方法;在接口中,可以直接添加非抽象的实例方法,在实例方法的申明中,需要增加default关键字修饰,因此这种方法也称为默认方 法(防御方法),他是接口自带的方法。
接口被实现后,实例可以直接使用这些默认方法,同时如果对默认方法需要重写时,可以直接重写即可。如下:
public interface SourceInterface
{
int a = 5;
int b = 10;
public static int add()
{
return a + b;
}
public default int f1()
{
return a;
}
}
调用时: SourceInterface.super.f1(); SourceInterface.add();
3.函数型接口(Functional): java.util.function
一个lambda在运行时的表现是一个函数型接口(或者说是一个“SAM类型”),一种只拥有仅仅一个抽象方法的接口。
所有的接口都标记上了@FunctionalInterface(http://download.java.net/jdk8/docs/api/java/lang/FunctionalInterface.html)运行时注解。
除了它在运行时通过注解用javac去确认是否真的是一个功能型接口以外,它里面就不能有更多的抽象方法了(但可以有防御方法)。如:
要想Java利用Groovy类型的迭代,我们就需要Collection和Iterable中都有一个新的方法。然而如果添加了这个方法,就将打破现有集合资源库的源代码级别的向后兼容性。因此,在Java 8中,java.util.Iterable 添加了forEach方法,并且为它提供了默认的实现。
public interface Iterable<T> {
Iterator iterator();
public default void forEach(Consumer consumer) {
for (T t : this) {
consumer.accept(t);
}
}
}
添加新的默认方法并没有打破源码级别的兼容性,因为接口的实现类并不需要提供它们自己对于这个方法的实现。
forEach方法利用了一个功能性接口作为参数,因而我们能够将一个lambda表达式作为一个参数传递进去。
4.方法引用使用一对冒号 :: ,通过方法的名字来指向一个方法。
list.forEach(System.out::println);
5.Stream(流):Java中的Stream并不会存储元素,而是按需计算。
- Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
- 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现
parallelStream其实就是一个并行执行的流,它通过默认的ForkJoinPool,可能提高你的多线程任务的速度。
Java8版本新增了很多新的方法,用于支持并行数组处理,如parallelSort():Arrays.parallelSort( arrayOfLong )
;
统计:
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum()); System.out.println("平均数 : " + stats.getAverage());
final Path path = new File( filename ).toPath();
try( Stream< String > lines = Files.lines( path, StandardCharsets.UTF_8 ) ) { lines.onClose( () -> System.out.println("Done!") ).forEach( System.out::println )}
6.Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
它可以保存类型T的值,或者仅仅保存null,Optional 类的引入很好的解决空指针异常。
void ifPresent(Consumer<? super T> consumer) 如果值存在则使用该值调用 consumer , 否则不做任何事情
T orElse(T other) 如果存在该值,返回值, 否则返回 other。
T orElseGet(Supplier<? extends T> other) 如果存在该值,返回值, 否则触发 other,并返回 other 调用的结果。
<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) 如果存在该值,返回包含的值,否则抛出由 Supplier 继承的异常
7.Java 8 Nashorn javascript
Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎。带来了2到10倍的性能提升。
使用 ScriptEngineManager, JavaScript 代码可以在 Java 中执行:
import javax.script.ScriptEngineManager; import javax.script.ScriptEngine; import javax.script.ScriptException;
public class Java8Tester{
public static void main(String args[]){
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
String name = "Runoob"; Integer result = null;
try {
nashorn.eval("print(‘" + name + "‘)");
result = (Integer) nashorn.eval("10 + 2");
}catch(ScriptException e){
System.out.println("执行脚本错误: "+ e.getMessage());
}
System.out.println(result.toString());}}
JavaScript中调用Java(需要使用 jjs 命令执行脚本?)
var BigDecimal = Java.type(‘java.math.BigDecimal‘);
function calculate(amount, percentage) {
var result = new BigDecimal(amount).multiply(
new BigDecimal(percentage)).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
return result.toPlainString();
}
var result = calculate(568000000000000000023,13.9);
print(result);
8.新的Date-Time API java.time.*
LocalDateTime now= LocalDateTime.now()
LocalDate date = LocalDate.of(2014, Month.DECEMBER, 12);
LocalTime time = LocalTime.of(22, 15);
final Duration duration = Duration.between( from, to ); //精确到纳秒
9.Base64
Stringbase64encodedString = Base64.getEncoder().encodeToString("runoob?java8".getBytes("utf-8")); byte[]base64decodedBytes = Base64.getDecoder().decode(base64encodedString); base64encodedString = Base64.getUrlEncoder().encodeToString("TutorialsPoint?java8".getBytes("utf-8"));
byte[]mimeBytes = stringBuilder.toString().getBytes("utf-8"); StringmimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
- 基本:输出被映射到一组字符A-Za-z0-9+/,编码不添加任何行标,输出的解码仅支持A-Za-z0-9+/。
- URL:输出映射到一组字符A-Za-z0-9+_,输出是URL和文件。
- MIME:输出隐射到MIME友好格式。输出每行不超过76字符,并且使用‘\r‘并跟随‘\n‘作为分割。编码输出最后没有行分割。(MIME, 全称为“Multipurpose Internet Mail Extensions”, 比较确切的中文名称为“多用途互联网邮件扩展”。)
10.重复注解
https://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
You can repeat an annotation anywhere
@Repeatable(Schedules.class)
public @interface Schedule {
String dayOfMonth() default "first";
String dayOfWeek() default "Mon";
int hour() default 12;
}
@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }
public @interface Schedules {
Schedule[] value();
}
The value of the @Repeatable
meta-annotation, in parentheses(圆括号), is the type of the container annotation that the Java compiler generates to store repeating annotations. In this example, the containing annotation type is Schedules
, so repeating @Schedule
annotations is stored in an @Schedules
annotation.
for( Schedule schedule: doPeriodicCleanup.class.getAnnotationsByType( Schedule.class ) ) { -----?
}
11.使用Metaspace(JEP 122)代替持久代(PermGen space)。在JVM参数方面,使用-XX:MetaSpaceSize和-XX:MaxMetaspaceSize代替原来的-XX:PermSize和-XX:MaxPermSize。
具体见JVM相关文档
12. 类依赖分析器:jdeps
13.并发性
为java.util.concurrent.ConcurrentHashMap类添加了新的方法来支持聚焦操作;也为java.util.concurrentForkJoinPool类添加了新的方法来支持通用线程池操作
Java 8还添加了新的java.util.concurrent.locks.StampedLock类,用于支持基于容量的锁——该锁有三个模型用于支持读写操作(可以把这个锁当做是java.util.concurrent.locks.ReadWriteLock的替代者)。
在java.util.concurrent.atomic包中也新增了不少工具类
date4 = LocalTime.of(22, 15);