java8增加的特性

2019/08/10 java语言

JAVA8增加的特性

​ Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日发布 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。

java8距今已经有五年时间,很多项目早已经在使用java8,相比较于java7,java8多了很多让人舒服的增强。

1、lambda表达式

lambda表达式(闭包)是java8版本中最大的一个特性,允许我们将函数作为参数传递给某个方法,或者直接把代码本身作为数据去处理。

  Arrays.asList("a","b","d").forEach((String s) -> System.out.println(s));
  Arrays.asList("a","b","d").forEach(s -> System.out.println(s));

函数接口,指的就是只有一个方法签名的接口,这样的接口可以转换成lambda表达式,为了保护这个函数接口,java8特出了一个注解,@FunctionalInterface 此注解方法接口上,如果接口声明第二个方法,则会报错,当然默认方法或者静态方法除外。

@FunctionalInterface
public interface functionDemo {
    void method();
    default void method2(){
        System.out.println("123");
    }
    static void  method3(){
        System.out.println("123");
    }
}

2、静态方法和默认方法

在java8中提供了静态方法和默认方法,默认方法的目的是为了开发者在不破坏实现类的情况下,对原有接口进行改造,不强制那些已经实现了接口的实现类再实现新的方法。注意,默认方法可以添加多个,没有限制。有了这个默认方法,接口在使用上则越来越靠近了抽象类。
@FunctionalInterface
public interface functionDemo {
    void method();
    default void method2(){
        System.out.println("123");
    }
    default void method4(){
        System.out.println("123");
    }
    static void  method3(){
        System.out.println("123");
    }
}

3、方法引用

​ 方法引用使得开发者可以直接引用现存的方法、Java类的构造方法或者实例对象。方法引用和Lambda表达式配合使用,使得java类的构造方法看起来紧凑而简洁,没有很多复杂的模板代码。

Arrays.sort(stringsArray,(s1,s2)->s1.compareToIgnoreCase(s2));
Arrays.sort(stringsArray, String::compareToIgnoreCase);

​ 方法引用大致上可以分为四种:

类型 示例
引用静态方法 ContainingClass::staticMethodName
引用某个对象的实例方法 containingObject::instanceMethodName
引用某个类型的任意对象的实例方法 ContainingType::methodName
引用构造方法 ClassName::new

4、重复注解

在java8之前,一个类,方法,属性上同种注解使用使用一个,java之后可以使用多个,首先,要对注解类进行修饰

使用@Repeatable注解定义重复注解。在使用的时候就可以定义多个注解,

    @Target( ElementType.TYPE )
    @Retention( RetentionPolicy.RUNTIME )
    @Repeatable( Filters.class )
    public @interface Filter {
        String value();
    };
    @Filter( "filter1" )
    @Filter( "filter2" )
    public interface Filterable {        
    }
    public static void main(String[] args) {
        for( Filter filter: Filterable.class.getAnnotationsByType( Filter.class ) ) {
            System.out.println( filter.value() );
        }
    } 

5、Optional

​ Java应用中最常见的bug就是空值异常。在Java 8之前,Google Guava引入了Optionals类来解决NullPointerException,从而避免源码被各种null检查污染,以便开发者写出更加整洁的代码。Java 8也将Optional加入了官方库。Optional仅仅是一个容易:存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查。

 Optional<String> test = Optional.ofNullable(null);
 System.out.println(test.isPresent());
 String zz =test.map(s -> s+="123").orElse("testset");
 System.out.println(zz);
      --------结果-----
  false
  testset     

6、Stream

​ 新增的Stream API(java.util.stream)将生成环境的函数式编程引入了Java库中。这是目前为止最大的一次对Java库的完善,以便开发者能够写出更加有效、更加简洁和紧凑的代码。Steam API极大得简化了集合操作。

 Arrays.asList(4,2,5,1,7,9).stream().sorted().forEach(i -> System.out.println(i));

Stream(流)是一个来自数据源的元素队列并支持聚合操作

  • 元素是特定类型的对象,形成一个队列。 Java中的Stream并不会存储元素,而是按需计算。
  • 数据源 流的来源。 可以是集合,数组,I/O channel, 产生器generator 等。
  • 聚合操作 类似SQL语句一样的操作, 比如filter, map, reduce, find, match, sorted等。

和以前的Collection操作不同, Stream操作还有两个基础的特征:

  • Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
  • 内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

Stream分为两种:

  1. stream() − 为集合创建串行流。
  2. parallelStream() − 为集合创建并行流。

Stream到底给我们带来了多少便利?

  1. forEach 排序操作,迭代流中的每个数据。random.ints().limit(10).forEach(System.out::println);
  2. map 映射每个元素到对应的结果,List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
  3. filter 过滤,符合添加的过滤掉 ` strings.stream().filter(string -> string.isEmpty())`
  4. limit 获取指定数量的流 random.ints().limit(10).forEach(System.out::println);
  5. sorted 对流进行排序 andom.ints().limit(10).sorted().forEach(System.out::println);
  6. paraller 并行流 List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 int count = strings.parallelStream().filter(string -> string.isEmpty()).count();
  7. 统计

7、Date 和Time的API

​ Java 8引入了新的Date-Time API(JSR 310)来改进时间、日期的处理。时间和日期的管理一直是最令Java开发者痛苦的问题。因为上面这些原因,诞生了第三方库Joda-Time,可以替代Java的时间管理API。Java 8中新的时间和日期管理API深受Joda-Time影响,并吸收了很多Joda-Time的精华。新的java.time包包含了所有关于日期、时间、时区、Instant(跟日期类似但是精确到纳秒)、duration(持续时间)和时钟操作的类。新设计的API认真考虑了这些类的不变性。

8、Nashorn JavaScript引擎

​ Java 8提供了新的Nashorn JavaScript引擎,使得我们可以在JVM上开发和运行JS应用。

9、Base64

  1. 对Base64编码的支持已经被加入到Java 8官方库中,这样不需要使用第三方库就可以进行Base64编码。

    String encoded = Base64
                .getEncoder()
                .encodeToString( text.getBytes( StandardCharsets.UTF_8 ) );
    String decoded = new String( 
                Base64.getDecoder().decode( encoded ),
                StandardCharsets.UTF_8 );
    

10、新的命令行工具Jdeps

jdeps是一个相当棒的命令行工具,它可以展示包层级和类层级的Java类依赖关系,它以.class文件、目录或者Jar文件为输入,然后会把依赖关系输出到控制台。简单测试一下:

jdeps DemoApplication.class
DemoApplication.class -> E:\program files\Java\jdk1.8\jre\lib\rt.jar
DemoApplication.class -> 找不到
   com.example.demo (DemoApplication.class)
      -> java.lang
      -> org.springframework.boot                           找不到
      -> org.springframework.boot.autoconfigure             找不到
      -> org.springframework.context                        找不到

在学习新的框架,找类依赖关系可以试试这个,比如spring-core包

jdeps spring-core-2.5.6.SEC03.jar
spring-core-2.5.6.SEC03.jar -> E:\program files\Java\jdk1.8\jre\lib\rt.jar
spring-core-2.5.6.SEC03.jar -> 找不到
   org.springframework.asm (spring-core-2.5.6.SEC03.jar)
      -> java.io
      -> java.lang
      -> java.lang.reflect
   org.springframework.asm.commons (spring-core-2.5.6.SEC03.jar)
      -> java.io
      -> java.lang
      -> java.security
      -> java.util
      -> org.springframework.asm                            spring-core-2.5.6.SEC03.jar
   org.springframework.asm.signature (spring-core-2.5.6.SEC03.jar)
      -> java.lang
   org.springframework.core (spring-core-2.5.6.SEC03.jar)
      -> edu.emory.mathcs.backport.java.util.concurrent     找不到
      -> java.io
      -> java.lang
      -> java.lang.ref
      -> java.lang.reflect
      -> java.util
      -> java.util.concurrent
      -> org.apache.commons.collections                     找不到
      -> org.apache.commons.collections.map                 找不到
      -> org.apache.commons.logging                         找不到
      -> org.springframework.asm                            spring-core-2.5.6.SEC03.jar
      -> org.springframework.asm.commons                    spring-core-2.5.6.SEC03.jar
      -> org.springframework.util                           spring-core-2.5.6.SEC03.jar
   org.springframework.core.annotation (spring-core-2.5.6.SEC03.jar)
   ...

Search

    欢迎添加我的个人微信号

    个人微信哦

    Table of Contents