前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDK8 新增功能 ( Java 语言新特性 )

JDK8 新增功能 ( Java 语言新特性 )

作者头像
张云飞Vir
发布2021-07-16 11:51:32
3660
发布2021-07-16 11:51:32
举报
文章被收录于专栏:写代码和思考

1. 背景

JDK8 是一个主要功能版本。本文档总结了其中的特性和增强功能。

说明:用更少的简洁文字和易读代码来表达。

2. Java 语言新特性

2.1 默认接口方法

在接口里可以写一个 “ 默认方法 ”,它可以在 不强制必须实现这个方法,从而很方便的往现存接口中添加新的方法。

代码语言:javascript
复制
package com.zhangyf.javademo.stage1;

/**
 * 示例:接口中写"默认方法"
 */
interface IDemo {
    void hello(); // 这个方法需要 "被实现"。

    // 默认方法,不需要  "被实现"。
    default void hi() {
        System.out.println("hi,zyf");
    }
}

class Demo1 implements IDemo {

    // 实现类仅仅 "实现 hello 方法就可。
    // 默认方法 hi 无需实现了。
    @Override
    public void hello() {
        System.out.println("hello,zyf");
    }
}

// 执行示例
class Stage1 {

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        demo1.hello();
        demo1.hi();
    }

}

“ 默认方法 ” 功能也称为扩展方法。适用于“ 为现有的类扩展新增新方法功能的场景 ”

2.2 lambda 表达式

代码语言:javascript
复制
/**
 * 示例:Lambda 表达式
 */
public class Stage2 {
    public static void main(String[] args) {
        List<String> names = Arrays.asList("banana", "apple", "mike", "xenia");
        // 使用 Lambda 时:很简洁。
        Collections.sort(names, (a, b) -> a.compareTo(b));
        System.out.println("排序后:" + names);
    }
}

再看下,当不用 Lambda ,传统写法,很长。

代码语言:javascript
复制
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

java 编译器知道参数类型,因此您也可以省略来写。

2.3 函数式接口

单方法接口(称为函数式接口)

函数式接口必须只包含一个抽象方法声明,为了防止意外的添加第二方法而导致错误,可以用 @FunctionalInterface 注解来加强声明定义,声明后编译器会帮你做检查符合函数式接口。

函数式接口 配合 Lambda 表达式可以更简洁地表达。

代码语言:javascript
复制
// 定义一个 " 函数式接口 ",它必须只有一个方法。
@FunctionalInterface
interface MyConverter<FROM, TO> {
    TO convert(FROM from);
}

class MainClass3 {

    public static void main(String[] args) {
        //使用 lambda 实现了一个 "函数式接口": 将 字符串 转换成 整数
        MyConverter<String, Integer> myConvert = (from) -> Integer.valueOf(from);
        //使用 "函数式接口"
        int intPara = myConvert.convert("1234");

        System.out.println(intPara);
    }

}

2.4 方法引用 ( 通过 :: 和方法名称 )

Java 8 允许您通过::关键字传递方法的引用。上面的例子进一步简化:

代码语言:javascript
复制
@FunctionalInterface
interface MyConverter1<FROM, TO> {
    TO convert(FROM from);
}

class MainClass4 {
    public static void main(String[] args) {
        MyConverter1<String, Integer> myConvert = Integer::valueOf;
        int intPara = myConvert.convert("1234");
        System.out.println(intPara);
    }
}

上面代码中的 Integer::valueOf 意思是 引用 Integer.valueOf 方法,可以作为参数传递使用了。

2.5 "方法引用" 也可以引用构造方法

代码语言:javascript
复制
class User {
    String name;
    int age;

    // 构造方法1:无参
    public User() {
    }

    // 构造方法2:两个参数
    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + "_" + age;
    }
}

// 一个工厂。注意是个 接口, 不是实现类
interface UserFactory {
    User create(String name, int age);
}

// 调用者
class MainClass5 {
    public static void main(String[] args) {
        // 通过方法引用了 User类的构造方法,好像 "粘" 在了一起。
        UserFactory userFactory = User::new;
        // 编译器通过推断,识别到 "这是两个参数的构造方法"
        User user = userFactory.create("zyf", 30);
        System.out.println(user);
    }
}

2.6 接口里可写“静态方法”

代码语言:javascript
复制
interface InterfaceDemo6 {
    static void createEntity() {
        System.out.println("createEntity....");
    }
}

// 调用者
class MainClass6 {
    public static void main(String[] args) {
        InterfaceDemo6.createEntity();
    }
}

2.7 可重复注解(一个注解可在方法里写多次)

以前在同一个地方不能多次使用同一个注解。Java 8引入了重复注解的概念,允许在同一个地方多次使用同一个注解。

代码语言:javascript
复制
@interface Hints {
    Hint[] value();
}

@Repeatable(Hints.class)
@interface Hint {
    String value();
}

@Hint("hint1")
@Hint("hint2")
class Person {
    ...
}

3. 扩展:内置的函数接口

JDK 1.8 API 包含许多内置 函数式接口(功能接口),这些接口经过 @FunctionalInterface 注解后 扩展已可以对 Lambda 支持。

3.1 谓词(Predicates)

根据给定的参数计算该谓词, 返回一个 boolean 结果。方法原型:

代码语言:javascript
复制
    boolean test(T t);

示例:

代码语言:javascript
复制
        // 谓词 Predicate
        Predicate<String> n1 = (s) -> s.length() > 0;
        boolean foo = n1.test("foo"); // true
        Predicate n2 = Objects::isNull;
        Predicate<String> n3 = String::isEmpty;

3.2 Functions

它可以引用一个 指定 一个参数,和返回值 的方法。

方法原型:

代码语言:javascript
复制
R apply(T t);

示例:

代码语言:javascript
复制
     // 功能 Function
        Function<String, Integer> f1 = Integer::valueOf;
        Integer interge1 = f1.apply("33432");

3.3 提供者 Supplier

它可以引用一个 构造方法。用于 返回一个对象

方法原型:

代码语言:javascript
复制
    T get();

示例:

代码语言:javascript
复制
// 提供者 Supplier ,它可以引用一个 构造方法
        Supplier supplier1 = Object::new;
        supplier1.get();

3.4 Consumers 消费者

Consumers, 它可以引用 "一个参数",无返回值的方法

方法原型:

代码语言:javascript
复制
    void accept(T t);

示例:

代码语言:javascript
复制
        Consumer<String> consumer1 = (str) -> System.out.println(str);
        Consumer<String> consumer2 = System.out::println;
        consumer2.accept("hello");

3.5 比较器 Comparator

方法原型:

代码语言:javascript
复制
    int compare(T o1, T o2);

示例:

代码语言:javascript
复制
Comparator<String> comparator1 = (p1, p2) -> p1.compareTo(p2);
comparator1.compare("P1","p3");

3.6 “可选的” Optional

Optional, 它不是一个 函数式接口。它 用于辅助判断 空值

代码语言:javascript
复制
        Optional<String> optional1 = Optional.of("some");
        optional1.isPresent(); // 有值,则 true
        optional1.get();

4. 流:Stream

Steam API极大得简化了集合操作,非常地强大。

代码语言:javascript
复制
// 准备演示数据
List<String> lst = new ArrayList<>();
lst.add("s1");
lst.add("s99");
lst.add("s3");
lst.add("ccc");
lst.add("zzz");
lst.add("111");

System.out.println("-------- 示例:filter ---------");
// filter 过滤器:接收一个表达式判断,返回boolean值,决定是否过滤掉
lst.stream().filter((it) -> it.startsWith("s")).forEach(System.out::println);

System.out.println("-------- 示例:sorted ---------");
// sorted:排序
lst.stream().sorted().forEach(System.out::println);

System.out.println("-------- 示例:map ---------");
// map:对子元素 map 映射后,成为新的集合
lst.stream().map(String::toUpperCase).forEach(System.out::println);

System.out.println("-------- 示例:匹配 ---------");
// anyMatch: 只要有一个 匹配成功
boolean result1 = lst.stream().anyMatch((s) -> s.startsWith("c"));
System.out.println(result1);// true
// allMatch: 都匹配成功,则为 true
boolean result2 = lst.stream().allMatch((s) -> s.startsWith("c"));
System.out.println(result2);// fasle
// noneMatch : 都不匹配,则为 true
boolean result3 = lst.stream().noneMatch((s) -> s.startsWith("$"));
System.out.println(result3);//

System.out.println("-------- 示例:count ---------");
// count: 计算总数。 先过滤 s 开头的,再计算个总数
long count1 = lst.stream().filter((p) -> p.startsWith("s")).count();
System.out.println("count1=" + count1);//

System.out.println("-------- 示例:reduce ---------");
// reduce: 归纳。 传入两个参数,返回一个结果
Optional<String> optional = lst.stream().sorted().reduce((t1, t2) -> t1 + "," + t2);
System.out.println("optional=" + optional);//

stream 也支持并行处理

参考我的另一篇文章:https://cloud.tencent.com/developer/article/1848275

5.扩展:日期 API

Java 8 在包下包含一个全新的日期和时间的API。

代码语言:javascript
复制
// 获得 系统的默认时区对应的 时钟对象
Clock clock = Clock.systemDefaultZone();
// 获得毫秒值
long millis = clock.millis();
System.out.println("millis: " + millis);

// 本地时间
LocalTime now1 = LocalTime.now();
System.out.println("now1: " + now1); // 23:34:46.112

// 本地时间
LocalDate now2 = LocalDate.now();
System.out.println("now2: " + now2); // 2021-07-13

// 本地时间
LocalDateTime now3 = LocalDateTime.now();
System.out.println("now2: " + now3); // 2021-07-13T23:34:46.113

// 持续时间
LocalDateTime start = LocalDateTime.now();
Thread.sleep(1234);
LocalDateTime end = LocalDateTime.now();
// 两个时间之间的差
Duration duration = Duration.between(start, end);
long mill = duration.toMillis();
System.out.println("mill: " + mill);

我的代码示例见:https://github.com/vir56k/java_demo/tree/master/java_new_feature_demo

6.参考:

更多新特性请阅读:https://www.oracle.com/java/technologies/javase/8-whats-new.html

Java 语言更新

https://docs.oracle.com/en/java/javase/15/language/java-language-changes.html#GUID-6459681C-6881-45D8-B0DB-395D1BD6DB9B

https://docs.oracle.com/javase/tutorial/java/index.html

https://docs.oracle.com/en/java/javase/15/language/local-variable-type-inference.html

https://www.oracle.com/java/technologies/javase/8-whats-new.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 背景
  • 2. Java 语言新特性
    • 2.1 默认接口方法
      • 2.2 lambda 表达式
        • 2.3 函数式接口
          • 2.4 方法引用 ( 通过 :: 和方法名称 )
            • 2.5 "方法引用" 也可以引用构造方法
              • 2.6 接口里可写“静态方法”
                • 2.7 可重复注解(一个注解可在方法里写多次)
                • 3. 扩展:内置的函数接口
                  • 3.1 谓词(Predicates)
                    • 3.2 Functions
                      • 3.3 提供者 Supplier
                        • 3.4 Consumers 消费者
                          • 3.5 比较器 Comparator
                            • 3.6 “可选的” Optional
                            • 4. 流:Stream
                            • 5.扩展:日期 API
                            • 6.参考:
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档