新特性你知道多少?

  • Java 8
  • Lambda 表达式
  • 接口增加默认方法等
  • 方法引用
  • 流 Stream
  • Java 9
  • 模块系统
  • 交互式工具jshell
  • .of() 创建不可变集合
  • 接口支持私有方法
  • 更好的 Try-with-resource 体验
  • Java 10
  • 局部变量类型推断 var
  • Java 11
  • var 支持 Lambda
  • 标准化的 HTTP Client API

Java 8

Java 8 中主要的新特性有4个。

Lambda 表达式

Lambda 表达式允许将函数作为一个方法的参数,即把函数作为参数传递进方法中。

示例如下:

public class Lambda {
    public static void main(String[] args) {
        // 类型声明
        MathOperation addition = (int a, int b) -> a + b;
        // 不用声明类型
        MathOperation subtraction = (a, b) -> 0;
        // 大括号中的返回语句
        MathOperation multiplication = (int a, int b) -> { return a * b; };
        // 没有大括号及返回语句
        MathOperation division = (int a, int b) -> a / b;

        Lambda lambda = new Lambda();
        System.out.println(lambda.operate(1,2,addition));

    }

    interface MathOperation {
        int operation(int a, int b);
    }

    interface GrecetingService {
        void sayMessage(String message);
    }

    private int operate(int a, int b, MathOperation mathOperation) {
        return mathOperation.operation(a, b);
    }
}

接口增加默认方法等

在 Java 8 以前,接口中只能有常量和抽象方法,不能含有方法的实现。但是在 Java 8 中,我们可以对接口添加默认实现,还可以实现静态方法。

示例:

public class InterfaceDefault {
    public static void main(String[] args) {
    }

    class LogOracle implements logging {
    }

    interface logging {
        String ORACLE = "Oracle_Database";
        String MYSQL = "Mysql_Database";

        default void logInfo(String message) {
            getConnection();
            System.out.println("Log Message : " + "INFO");
            closeConnection();
        }

        static void getConnection() {
            System.out.println("Open Database connection");
        }

        static void closeConnection() {
            System.out.println("Close Database connection");
        }
    }

}

方法引用

方法引用通过方法的名字来指向一个方法.

示例:

public class MethodReference {
    public static void main(String[] args) {f
        // 方法引用使用一对冒号 :: 来实现
        List names = new ArrayList();

        names.add("Google");
        names.add("Runoob");
        names.add("Taobao");
        names.add("Baidu");
        names.add("Sina");
        
        names.forEach(System.out::println);
    }
}

流 Stream

Java 8 API 添加了一个称为流 Stream 的新的抽象,通过使用 Stream 可以提高程序员的生产力,让程序员写出高效、干净、简洁的代码。

流 Stream 将要处理的元素集合看作一种流,流可以在管道中传输,并且可以在管道的节点上进行处理,比如过滤筛选,排序,聚合等。

示例:

public class Stream {
    public static void main(String[] args) {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        System.out.println("列表: " + strings);

        long count = strings.stream().filter(string -> string.isEmpty()).count();
        System.out.println("空字符串数量为: " + count);

        count = strings.stream().filter(string -> string.length() == 3).count();
        System.out.println("字符串长度为 3 的数量为: " + count);

        List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
        System.out.println("筛选后的列表: " + filtered);

        String collect = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(","));
        System.out.println("合并字符串:" + collect);

        //*********************//

        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        List<Integer> integers = Arrays.asList(1, 2, 13, 4, 15, 6, 17, 8, 19);

        List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
        System.out.println("Squares List: " + squaresList);
        System.out.println("列表: " + integers);

        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());
        System.out.println("随机数: ");

        // 输出10个随机数
        Random random = new Random();

        for (int i = 0; i < 10; i++) {
            System.out.println(random.nextInt());
        }

        random.ints().limit(10).sorted().forEach(System.out::println);

        // 并行处理
        count = strings.parallelStream().filter(string -> string.isEmpty()).count();
        System.out.println("空字符串的数量为: " + count);
    }
}

Java 9

Java 9 中最值得关注的就是引入了模块系统,还有其他一些特性如下。

模块系统

Java 9 引入了模块系统,并且将 JDK 也进行了模块化。在以前,不管我们做什么项目(有可能就是很小的一个demo项目)都需要包含 JDK 中所有的包,这样会导致程序包非常大。将 JDK 模块化后,当用到某些模块时,之引入具体的模块,这样会大大减小程序包。

JDK 9 中一共由 94 个模块组成,通过新增的 jlink 工具可以创建出每个应用独有的 Java 运行时镜像。

交互式工具jshell

Java 9 增加了新特性 jshell ,在 jshell 中可以直接输入表达式并查看执行结果。
当我们需要测试一个方法的运行效果,或是快速的对表达式进行求值时,jshell 都非常实用。

.of() 创建不可变集合

在集合中, java 9 增加了 List.of()、Set.of()、Map.of() 等工厂方法来创建不可变集合。在这之前,如果我们需要创建不可变集合,需要借助 Collections.unmodifiableSet() 等方法来实现。

接口支持私有方法

在 Java 8 中,接口引入了新的支持 一一 默认方法和静态方法。
在 Java 9 中,接口又引入了对私有方法的支持。
示例:

interface logging {
        String ORACLE = "Oracle_Database";
        String MYSQL = "Mysql_Database";

        private void log(String message, String prefix) {
            getConnection();
            System.out.println("Log Message : " + prefix);
            closeConnection();
        }

        default void logInfo(String message) {
            log(message, "INFO");
        }

        static void getConnection() {
            System.out.println("Open Database connection");
        }

        static void closeConnection() {
            System.out.println("Close Database connection");
        }
    }

更好的 Try-with-resource 体验

Java 7 引入了 Try-with-resource,使得我们可以更方便地对资源进行关闭,但是我们必须得对资源对象进行声明。
Java 9 中去除了这一限制,使得对资源的管理更加方便。
示例:

private static String beforeJava9(String message) throws IOException {
        Reader inputString = new StringReader(message);
        BufferedReader br = new BufferedReader(inputString);
        try (BufferedReader br1 = br) {
            return br1.readLine();
        }
    }

    private static String Java9(String message) throws IOException {
        Reader inputString = new StringReader(message);
        BufferedReader br = new BufferedReader(inputString);
        try (br) {
            return br.readLine();
        }
    }

Java 10

局部变量类型推断 var

Java 10 中我觉得最值得说的就属局部变量类型推断 var 了,它能够帮助我们更加快速地编写简洁的代码。但是使用 var 使得我们不容易分辨变量的类型,利弊各有吧。
示例:

public class LocalVariableTypeInference {
    public static void main(String[] args) {
        var list = new ArrayList<String>();
        list.add("2");
        System.out.println(list.toString());
        var stream = list.stream();
        System.out.println(stream.toString());
    }
}

Java 11

var 支持 Lambda

Java 10 虽然引入了 var 保留字,但是其不能在 Lambda 中声明使用,在 Java 11 中克服了这一弊端。
示例:

// (var x, var y) -> x.process(y)
//  等价于
//  (x, y) -> x.process(y)

标准化的 HTTP Client API

Java 11 中将 HttpClient 变成了原生的,在这之前,我们使用 HttpClient时,需要引入 apache 的包。