java8 新特性

Posted wzbinstu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8 新特性相关的知识,希望对你有一定的参考价值。

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.使用MetaspaceJEP 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);



 


















以上是关于java8 新特性的主要内容,如果未能解决你的问题,请参考以下文章

2020了你还不会Java8新特性?Java 8新特性介绍

java8新特性——Lambda表达式

Java8新特性

java8新特性总结

Java8新特性

Java8新特性-官方库新特性