跳至主要內容

java8新特性

zheng大约 4 分钟java基础JDK1.8新特性

都9102年了,JAVA出到了13.0.1。现在预习一下JAVA8新特性应该还来得及;用代码说话:

一、Stream(流)

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

数据源是流的来源。 数据源可以是集合,数组,I/O channel等

优点:

  • 内部迭代:通过访问者模式(Visitor)实现
  • Pipelining:中间操作都会返回流对象本身
  • 聚合操作:类似SQL语句一样的操作, 比如 filter, map, reduce, find, match, sorted 等
package com.bjut.java8test;

import org.junit.Test;

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class Java8StreamTest {
    final List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
    final List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
    final Random random = new Random();

    @Test
    public void filter() {
        // filter 方法过滤出空字符串
        List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
        System.out.println(filtered);
    }

    @Test
    public void forEach() {
        // Stream 提供了新的方法 'forEach' 来迭代流中的每个数据;limit 方法用于获取指定数量的流
        random.ints().limit(10).forEach(System.out::println);
    }

    @Test
    public void map() {
        // map 方法用于映射每个元素到对应的结果
        // 获取对应的平方数, distinct为去重
        List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
        System.out.println(squaresList);
    }

    @Test
    public void sorted() {
        // sorted 方法用于对流进行排序
        random.ints().limit(10).sorted().forEach(System.out::println);
    }

    @Test
    public void parallel() {
        // 获取空字符串的数量
        long count = strings.parallelStream().filter(string -> string.isEmpty()).count();
        System.out.println(count);
    }

    @Test
    public void join() {
        // 类似于
        // jdk:String mergedString = String.join(",", strings);
        // common.lang3:String mergedString = StringUtils.join(strings);

        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(","));
        System.out.println(mergedString);
    }

    @Test
    public void statistics(){
        // 一些产生统计结果的收集器也非常有用。它们主要用于int、double、long等基本类型上
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        IntSummaryStatistics stats = numbers.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());
    }

}


二、方法引用

方法引用

方法引用提供了非常有用的语法,可以直接引用已有Java类或对象(实例)的方法或构造器。

package com.bjut.java8test;

@FunctionalInterface
public interface Supplier<T>{
    T get();
}

package com.bjut.java8test;

public class Car {
    // Supplier是jdk1.8的接口,这里和lamda一起使用了
    public static Car create(final Supplier<Car> supplier) {
        return supplier.get();
    }

    public static void collide(final Car car) {
        System.out.println("Colloded" + car.toString());
    }

    public void follow(final Car another) {
        System.out.println("Following the" + another.toString());
    }

    public void repair() {
        System.out.println("Repaired" + this.toString());
    }
}
package com.bjut.java8test;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Java8QuoteTest {
    final Car car = Car.create(Car::new);
    final List<Car> cars = Arrays.asList(car);
    final Car police = Car.create(Car::new);

    @Test
    public void quoteType() {
        // 静态方法引用:它的语法是Class::static_method,实例如下:
        cars.forEach(Car::collide);
        // 特定类的任意对象的方法引用:它的语法是Class::method实例如下:
        cars.forEach(Car::repair);
        // 特定对象的方法引用:它的语法是instance::method实例如下:
        cars.forEach(police::follow);
    }

    @Test
    public void quoteExample(){
        List<String> names = new ArrayList<>(50);
        names.add("hello");
        names.add("world");
        names.add("ni");
        names.add("hao");
        names.forEach(System.out::println);
    }
}

三、默认方法

默认方法 − 默认方法就是一个在接口里面有了一个实现的方法。

package com.bjut.java8test;

public interface Java8DefaultInterface {
    default void print(){
        System.out.println("默认方法");
    }
}

package com.bjut.java8test;

import org.junit.Test;

/**
 * 测试接口默认方法
 */
public class Java8DefaultInterfaceTest implements Java8DefaultInterface{

    @Test
    public void test(){
        Java8DefaultInterface defaultInterface = new Java8DefaultInterfaceTest();
        defaultInterface.print();
    }
}

四、 Date Time API

加强对日期与时间的处理。

package com.bjut.java8test;

import org.junit.Test;
import java.time.*;

public class Java8DateTest {
    LocalDateTime currentTime = LocalDateTime.now();

    @Test
    public void testLocalDateTime() {
        // 获取服务器当前的日期时间
        System.out.println("时间" + currentTime);

        // 获取服务器当前日期
        LocalDate date1 = currentTime.toLocalDate();
        System.out.println("date1: " + date1);

        // 获取服务器某月某天
        Month month = currentTime.getMonth();
        int day = currentTime.getDayOfMonth();
        int seconds = currentTime.getSecond();
        System.out.println("月: " + month + ", 日: " + day + ", 秒: " + seconds);
    }

    @Test
    public void testStructDateTime() {
        LocalDateTime date2 = currentTime.withDayOfMonth(12).withYear(2012);
        System.out.println("date2" + date2);

        // 23 december 2014
        LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 23);
        System.out.println("date3" + date3);

        // 22 小时 15 分钟
        LocalTime date4 = LocalTime.of(22, 15);
        System.out.println("date4: " + date4);

        // 解析字符串
        LocalTime date5 = LocalTime.parse("20:15:30");
        System.out.println("date5: " + date5);
    }

    @Test
    public void testZonedDateTime() {
        // 获取当前时间日期
        ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
        System.out.println("date1: " + date1);

        ZoneId id = ZoneId.of("Europe/Paris");
        System.out.println("ZoneId: " + id);

        ZoneId currentZone = ZoneId.systemDefault();
        System.out.println("当期时区: " + currentZone);
    }
}

五、 Optional 类

Optional 类是一个可以为null的容器对象。优雅的解决null问题:我平时好像都是类似于 StringUtils.isBlank()

JAVA9在它的基础上又增加了3个方法

package com.bjut.java8test;

import org.junit.Test;
import java.util.Optional;

public class java8OptionalTest {

    @Test
    public void testOptional() {
        Integer value1 = null;
        Integer value2 = new Integer(10);

        // Optional.ofNullable -允许传递null参数
        Optional<Integer> a = Optional.ofNullable(value1);
        // Optional.of - 如果传递的参数是null , 抛出异常NullPointerException
        Optional<Integer> b = Optional.of(value2);

        System.out.println(sum(a, b));
    }


    private Integer sum(Optional<Integer> a, Optional<Integer> b) {
        // Optional.isPresent - 判断值是否存在
        System.out.println("第一个参数值存在" + a.isPresent());
        System.out.println("第二个参数值存在" + b.isPresent());

        // Option.orElse - 如果值存在,返回它,否则返回默认值
        Integer value1 = a.orElse(new Integer(0));

        // Optional.get - 获取值,值需要存在
        Integer value2 = b.get();
        return value1 + value2;
    }
}

参考文献:https://www.runoob.com/java/java8-new-features.htmlopen in new window

上次编辑于:
贡献者: 郑天祺