JDK1.8 新特性之Optional的常用方法

本文详细介绍了一个基于Java实现的员工类,包括属性、构造方法和覆盖方法。同时,通过测试用例展示了Optional类的各种使用场景,如创建实例、判断值存在、获取默认值等。

基础类(员工类):

import java.util.Objects;

// 员工信息
public class Employee {
    private String name; // 姓名
    private Integer age; // 年龄
    private Double salary; // 工资
    private Status status; // 状态

    public enum Status {
        FREE,
        BUSY,
        VOCATION;
    }

    public Employee() {}
    public Employee(String name, Integer age, Double salary) {
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Employee(String name, Integer age, Double salary, Status status) {
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.status = status;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Double getSalary() {
        return salary;
    }

    public void setSalary(Double salary) {
        this.salary = salary;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                ", status=" + status +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return Objects.equals(name, employee.name) &&
                Objects.equals(age, employee.age) &&
                Objects.equals(salary, employee.salary);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, salary);
    }
}

测试用例:

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

/**
 * Optional常用方法测试:
         Optional.of(T t): 创建一个Optional实例
         Optional.empty(): 创建一个空的Optional实例
         Optional.ofNullable(T t): 若t 不为null, 创建Optional实例,否则创建空实例
         isPresent(): 判断是否包含值
         orElse(T t): 如果调用对象包含值,返回该值, 否则返回t.
         orElseGet: 如果调用对象包含值, 返回该值, 否则返回s获取的值
         map: 如果有值对其处理, 并返回处理后的Optional, 否则返回Optional.empty()
         flatMap: 与map类似, 要求返回值必须是Optional
 */
public class OptionalTest {
    @Test
    public void demo1() {
        System.out.println("------ 创建一个Optional实例 ----------");
        Optional<Employee> op1 = Optional.of(new Employee());
        System.out.println(op1.get());

        System.out.println("----- 创建一个空的Optional实例 ------");
        Optional<Employee> op2 = Optional.empty();
        System.out.println(op2.isPresent()? "op2的值不为空": "op2的值为空");

        System.out.println("-- 若t 不为null, 创建Optional实例,否则创建空实例 ------");
        Optional<Employee> op3 = op2.ofNullable(new Employee("张三", 12, 2222.22, Employee.Status.BUSY));
        Optional<Employee> op31 = Optional.ofNullable(new Employee("张三", 12, 2222.22, Employee.Status.BUSY));
        System.out.println("op3: " + op3.get());
        System.out.println("op31: " + op31.get());

        System.out.println("--------------- isPresent:判断是否包含值 ---------------");
        if (op2.isPresent()) {
            System.out.println("op2不为空");
        } else {
            System.out.println("op2为空");
        }

        if (op3.isPresent()) {
            System.out.println("op3不为空");
        } else {
            System.out.println("op3为空");
        }

        System.out.println("--------- 如果调用对象包含值,返回该值, 否则返回t. ----------");
        Employee emp1 = op2.orElse(new Employee("李四", 13, 3333.33, Employee.Status.FREE));
        System.out.println("emp1: " + emp1);

        Employee emp2 = op3.orElse(new Employee("李四", 13, 3333.33, Employee.Status.FREE));
        System.out.println("emp2: " + emp2);

        System.out.println("------ 如果调用对象包含值, 返回该值, 否则返回s获取的值 ------");
        op2.orElseGet(() -> new Employee("王五", 19, 444.44, Employee.Status.VOCATION));

        System.out.println("--- 如果有值对其处理, 并返回处理后的Optional, 否则返回Optional.empty() ---");
        Optional<String> op4 = op2.map((e) -> e.getName());
        Optional<String> op5 = op3.map((e) -> e.getName());
        System.out.println("op4: " + op4);
        System.out.println("op5: " + op5);

        System.out.println("------ 与map类似, 要求返回值必须是Optional -----");
        Optional<String> op6 = op2.flatMap(e -> Optional.of(e.getName()));
        Optional<String> op7 = op3.flatMap(e -> Optional.of(e.getName()));
        System.out.println("op6: " + op6);
        System.out.println("op7: " + op7);
    }
}

 

<think>好的,用户现在想了解JDK 1.8新特性列表及详细说明。之前我回答过关于数据库乐观锁实现分布式锁的问题,现在需要结合用户提供的站内引用内容来回答。让我先看看用户提供的引用内容。 引用[1]提到了`removeIf`方法,属于集合框架的增强,还涉及`Predicate`接口和`Function`接口的例子。引用[2]展示了构造器引用和数组引用,属于方法引用的部分。引用[3]关于使用Lambda表达式简化`Comparator`,涉及Lambda和函数式接口。引用[4]则提到了用Lambda表达式实现`Runnable`,进一步说明函数式编程的应用。这些引用都是JDK 1.8新特性,主要集中在Lambda表达式、函数式接口、方法引用等方面。 用户的问题是要了解JDK 1.8新特性列表及详细说明。我需要整理出主要的新特性,并参考用户提供的引用内容来举例说明。首先,应该涵盖Lambda表达式、函数式接口、方法引用、Stream API、接口的默认方法和静态方法、新的日期时间API、Optional类、Nashorn JavaScript引擎等。 需要注意的是,用户提供的引用中提到了`removeIf`、`Predicate`、`Function`、构造器引用、数组引用、Lambda在`Comparator`和`Runnable`中的应用,这些都需要在回答中详细说明,并结合例子。例如,在讲解Lambda表达式时,可以用用户提供的`Runnable`例子;在函数式接口部分,可以提到`Predicate`和`Function`;方法引用部分可以用构造器和数组引用的例子。 另外,用户可能对实际应用场景感兴趣,所以每个特性需要给出具体的代码示例,比如`removeIf`的使用,`Arrays.sort`与Lambda的结合,方法引用的简化写法等。同时,要确保回答结构清晰,分点说明,帮助用户逐步理解各个特性。 还要考虑用户可能存在的疑问,比如为什么引入这些特性,它们带来了哪些好处,比如代码简洁性、函数式编程的支持、并行处理能力提升等。在讲解Stream API时,可以对比传统的集合操作,突出其优势。 最后,生成的相关问题需要围绕这些新特性,可能涉及具体使用场景、性能优化、与其他版本的区别等,确保问题能够引导用户进一步深入学习。</think>### JDK 1.8 新特性详解 #### 一、Lambda 表达式 **定义**:允许以简洁的语法实现函数式接口的匿名方法。 **语法**:`(参数) -> { 表达式或代码块 }` **应用场景**:简化匿名内部类,支持函数式编程。 **示例**: ```java // 传统 Runnable 实现 new Thread(new Runnable() { @Override public void run() { System.out.println("run方法执行了"); } }).start(); // Lambda 表达式优化[^4] new Thread(() -> System.out.println("run方法执行了")).start(); ``` #### 二、函数式接口(Functional Interface) **定义**:仅包含**一个抽象方法**的接口,可用 `@FunctionalInterface` 注解标记。 **常见内置接口**: 1. **Predicate<T>** 用于条件判断,示例:集合的 `removeIf` 方法 ```java list.removeIf(s -> s.contains("o")); // 删除包含字母"o"的元素[^1] ``` 2. **Function<T, R>** 用于类型转换,示例:字符串首字母大写 ```java Function<String, String> fun = s -> s.substring(0,1).toUpperCase() + s.substring(1); System.out.println(fun.apply("hello")); // 输出 "Hello"[^1] ``` 3. **Comparator<T>** 用于对象排序,示例:按年龄排序 ```java Arrays.sort(rosterAsArray, (a, b) -> a.getAge().compareTo(b.getAge()));[^3] ``` #### 三、方法引用与构造器引用 **定义**:通过 `::` 符号简化 Lambda 表达式。 **分类**: 1. **静态方法引用**:`类名::静态方法` 2. **实例方法引用**:`对象::实例方法` 3. **构造器引用**:`类名::new` **示例**: ```java // 构造器引用:String -> Integer Function<String, Integer> fun1 = Integer::new; // 等价于 num -> new Integer(num)[^2] // 数组引用:Integer -> Integer[] Function<Integer, Integer[]> fun2 = Integer[]::new; // 等价于 num -> new Integer[num][^2] ``` #### 四、Stream API **核心功能**:对集合进行**链式流水线操作**,支持并行处理。 **操作类型**: | 类型 | 方法示例 | 说明 | |------------|---------------------------|------------------| | 中间操作 | `filter()`, `map()`, `sorted()` | 惰性执行,返回新流 | | 终结操作 | `forEach()`, `collect()`, `count()` | 触发实际计算 | **示例**: ```java List<String> list = Arrays.asList("a", "b", "c"); list.stream() .filter(s -> !s.equals("b")) // 过滤掉"b" .map(String::toUpperCase) // 转为大写 .forEach(System.out::println); // 输出 A C ``` #### 五、接口的默认方法与静态方法 1. **默认方法(Default Method)** 使用 `default` 关键字,允许接口提供默认实现,避免破坏现有代码。 ```java public interface Collection<E> { default boolean removeIf(Predicate<? super E> filter) { // 默认实现[^1] } } ``` 2. **静态方法** 接口中可直接定义静态工具方法。 ```java public interface Path { static Path get(String first, String... more) { return FileSystems.getDefault().getPath(first, more); } } ``` #### 六、新的日期时间 API(java.time) **核心类**: - `LocalDate`:日期(年-月-日) - `LocalTime`:时间(时:分:秒) - `LocalDateTime`:日期时间 - `ZonedDateTime`:带时区的日期时间 **示例**: ```java LocalDate date = LocalDate.now(); // 2023-07-20 LocalDateTime datetime = date.atTime(14, 30); // 2023-07-20T14:30 ``` #### 七、Optional 类 **作用**:解决 `NullPointerException` 问题,明确处理空值。 **常用方法**: - `Optional.ofNullable(value)`:包装可能为 null 的值 - `orElse(defaultValue)`:提供默认值 - `ifPresent(Consumer)`:值存在时执行操作 **示例**: ```java Optional<String> name = Optional.ofNullable(getName()); System.out.println(name.orElse("Unknown")); ``` #### 八、其他特性 1. **Nashorn JavaScript 引擎** 替代 Rhino 引擎,支持在 JVM 中运行 JavaScript 代码。 ```java ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); engine.eval("print('Hello Nashorn!');"); ``` 2. **重复注解** 允许同一位置多次使用相同注解。 ```java @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri") public void scheduledTask() { /* ... */ } ``` --- ### 新特性对比(JDK 1.7 vs 1.8) | 特性 | JDK 1.7 | JDK 1.8 | |---------------------|----------------------------|--------------------------------------| | 集合操作 | 手动迭代+条件判断 | Stream API 链式操作 | | 函数式编程 | 匿名内部类 | Lambda 表达式 + 函数式接口 | | 空值处理 | `if (obj != null)` 校验 | Optional 类明确处理 | | 接口扩展性 | 无法添加新方法 | 默认方法实现 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值