首页 > 编程语言 >Java 8 特性: Lambda 表达式、Stream API、Optional 类等

Java 8 特性: Lambda 表达式、Stream API、Optional 类等

时间:2024-12-22 15:03:10浏览次数:7  
标签:Java String Stream System API println Optional out

Java 8 引入了很多新的特性,极大地增强了 Java 语言的表达能力和开发效率。以下是一些主要的新特性

1.Lambda 表达式

Lambda 表达式允许以更简洁的方式表示匿名函数,使得代码更加简洁和可读。它支持函数式编程风格,并可以作为参数传递给方法。

语法:

    (parameters) -> expression

示例:

    // 使用Lambda表达式表示Runnable接口
    // Lambda 表达式 无参数:如果没有参数,可以省略括号
    //  一个参数:如果只有一个参数,括号可以省略。 x -> x * x   //传入一个参数并返回其平方
    // 多个参数:多个参数时需要使用括号来包含。(x, y) -> x + y   //传入两个参数并返回它们的和
    // 带有代码块:如果 Lambda 表达式的主体包含多个语句,需要使用大括号 {} 来包裹代码块
    // (x, y) -> {
    // int sum = x + y;
    // return sum;
    // }
Runnable
r = () -> System.out.println("Hello from Lambda");
r.run();

Lambda 表达式的优势

  • 简化代码:Lambda 表达式使得代码更加简洁,减少了冗长的匿名类代码。
  • 提高可读性:通过明确的行为表达式,Lambda 让代码变得更加直观和易于理解。
  • 支持函数式编程:Lambda 表达式使得 Java 更好地支持函数式编程,支持高阶函数、组合函数等。
  • 与 Stream API 结合使用:与 Java 8 引入的 Stream API 结合,Lambda 可以方便地处理集合数据,进行过滤、映射、排序等操作。

Lambda 表达式的实际应用场景

  • 集合框架:通过 Lambda 表达式简化集合元素的操作,特别是在 List、Set、Map 等集合上进行过滤、映射、排序等操作。
  • 事件处理:在 GUI 编程中,Lambda 可以简化事件监听器的实现。
  • 函数式接口:Java 8 中定义了很多函数式接口(如 Runnable、Callable、Comparator 等),可以通过 Lambda 表达式来简化它们的实现。

2.Java 8 java.util.function 包及常见接口详解

Java 8 引入了 java.util.function 包,该包提供了一组核心函数式接口,支持 Lambda 表达式和方法引用。这些接口简化了代码,使其更加简洁、可读和易于维护。


常用的函数式接口一览

接口名描述函数式方法
Predicate<T>条件判断(过滤)boolean test(T)
Function<T, R>类型转换(映射)R apply(T)
Consumer<T>消费型操作(无返回)void accept(T)
Supplier<T>供给型操作(返回数据)T get()
UnaryOperator<T>一元运算符(同类型转换)T apply(T)
BinaryOperator<T>二元运算符(同类型运算)T apply(T, T)

1. Predicate<T>:条件判断

Predicate<T> 用于条件判断,常用于过滤操作。

核心方法:

  • boolean test(T t):对给定的输入执行判断,返回布尔值。

默认方法:

  • and(Predicate other):逻辑与操作。
  • or(Predicate other):逻辑或操作。
  • negate():逻辑非操作。

示例:判断字符串是否为空

import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<String> isEmpty = String::isEmpty;
        Predicate<String> isNotEmpty = isEmpty.negate();
        System.out.println(isEmpty.test(""));   // 输出: true
        System.out.println(isNotEmpty.test("Java")); // 输出: true
    }
}

2. Function<T, R>:类型转换

Function<T, R> 用于将一个类型转换为另一个类型,常用于映射操作。

核心方法:

  • R apply(T t):将输入参数 T 转换为结果 R

默认方法:

  • andThen(Function after):在当前函数执行后执行另一个函数。
  • compose(Function before):在当前函数执行前执行另一个函数。

示例:字符串长度映射与组合

import java.util.function.Function;

public class FunctionExample {
    public static void main(String[] args) {
        Function<String, Integer> strLength = String::length;
        Function<Integer, Integer> doubleValue = x -> x * 2;

        System.out.println(strLength.apply("Java"));  // 输出: 4
        System.out.println(strLength.andThen(doubleValue).apply("Java"));  // 输出: 8
    }
}

3. Consumer<T>:数据消费

Consumer<T> 用于操作数据,没有返回值,常用于打印或存储。

核心方法:

  • void accept(T t):接收参数并执行操作。

默认方法:

  • andThen(Consumer after):组合多个消费者操作。

示例:打印数据并组合操作

import java.util.function.Consumer;

public class ConsumerExample {
    public static void main(String[] args) {
        Consumer<String> printer = System.out::println;
        Consumer<String> greeter = name -> System.out.println("Hello, " + name);

        printer.accept("Java!"); // 输出: Java!
        greeter.andThen(printer).accept("World"); // 输出: Hello, World
        // 输出: World
    }
}

4. Supplier<T>:数据提供

Supplier<T> 提供数据,没有输入参数,常用于生成数据。

核心方法:

  • T get():返回一个结果。

示例:生成随机数与当前时间

import java.util.function.Supplier;
import java.util.Random;

public class SupplierExample {
    public static void main(String[] args) {
        Supplier<Integer> randomNumber = () -> new Random().nextInt(100);
        Supplier<Long> currentTime = System::currentTimeMillis;

        System.out.println("随机数: " + randomNumber.get());  // 输出: 随机整数
        System.out.println("当前时间: " + currentTime.get()); // 输出: 当前时间戳
    }
}

5. UnaryOperator<T>:一元运算

UnaryOperator<T> 是特殊的 Function<T, T>,用于相同类型的数据转换。

核心方法:

  • T apply(T t):将输入参数 T 转换为 T

示例:将字符串转换为大写

import java.util.function.UnaryOperator;

public class UnaryOperatorExample {
    public static void main(String[] args) {
        UnaryOperator<String> toUpperCase = String::toUpperCase;
        System.out.println(toUpperCase.apply("java"));  // 输出: JAVA
    }
}

6. BinaryOperator<T>:二元运算

BinaryOperator<T> 是特殊的 BiFunction<T, T, T>,用于两个相同类型的数据运算。

核心方法:

  • T apply(T t1, T t2):对两个参数执行操作并返回结果。

示例:两个整数相加与最大值比较

import java.util.function.BinaryOperator;

public class BinaryOperatorExample {
    public static void main(String[] args) {
        BinaryOperator<Integer> add = Integer::sum;
        BinaryOperator<Integer> max = Integer::max;

        System.out.println("求和: " + add.apply(5, 3));  // 输出: 8
        System.out.println("最大值: " + max.apply(5, 3));  // 输出: 5
    }
}

总结

java.util.function 包提供的接口能够帮助我们以更加简洁的方式实现函数式编程。Lambda
表达式和这些接口的结合,使得代码更加简洁和易于理解。熟练掌握这些接口,可以在日常开发中写出更优雅的代码。

Java Stream API 深入解析与实用示例

Java 8 引入了 Stream API,极大简化了对集合数据的处理。通过流操作,开发者可以实现复杂的数据操作,如过滤、排序和聚合,代码更简洁、更具可读性。


3.什么是 Stream API?

Stream API 提供了一种函数式编程风格的数据处理方式,主要用于对集合数据(如 List, Set, Map)进行操作。它支持以下功能:

  • 过滤(Filtering)
  • 映射(Mapping)
  • 排序(Sorting)
  • 统计与聚合(Reduction)
  • 收集结果(Collecting)

Stream 流的生命周期

Stream 的使用包含以下三个步骤:

  1. 创建流 (Stream Source): 从集合、数组等数据源创建流。
  2. 中间操作 (Intermediate Operations): 对数据执行链式转换操作。
  3. 终止操作 (Terminal Operations): 执行终结操作,如收集结果或计算。

3.Stream 的常见操作与示例

1. 创建流 (Stream Creation)

  • 从集合创建流:

    List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
    Stream<String> nameStream = names.stream();
    
  • 从数组创建流:

    int[] numbers = {1, 2, 3, 4, 5};
    IntStream numberStream = Arrays.stream(numbers);
    
  • 使用 Stream.of() 方法:

    Stream<String> stream = Stream.of("Java", "Python", "C++");
    

2. 中间操作 (Intermediate Operations)

1. 过滤 (filter)
  • 过滤出长度大于 3 的字符串:
    List<String> names = Arrays.asList("Java", "C", "Python", "Go");
    names.stream()
        .filter(name -> name.length() > 2)
        .forEach(System.out::println);
    
2. 映射 (map)
  • 将字符串转换为大写:
    List<String> languages = Arrays.asList("java", "python", "go");
    languages.stream()
        .map(String::toUpperCase)
        .forEach(System.out::println);
    
3. 排序 (sorted)
  • 按字母顺序排序:
    List<String> fruits = Arrays.asList("Apple", "Orange", "Banana");
    fruits.stream()
        .sorted()
        .forEach(System.out::println);
    
4. 去重 (distinct)
  • 去除重复的元素:
    List<Integer> numbers = Arrays.asList(1, 2, 2, 3, 3, 4);
    numbers.stream()
        .distinct()
        .forEach(System.out::println);
    
5. 限制和跳过 (limit / skip)
  • 获取前两个元素:

    Stream.of("A", "B", "C", "D")
        .limit(2)
        .forEach(System.out::println);
    
  • 跳过前两个元素:

    Stream.of("A", "B", "C", "D")
        .skip(2)
        .forEach(System.out::println);
    

3. 终结操作 (Terminal Operations)

1. 收集 (collect)
  • 将流转换为集合:
    List<String> filteredNames = names.stream()
        .filter(name -> name.length() > 3)
        .collect(Collectors.toList());
    System.out.println(filteredNames);
    
2. 统计 (count)
  • 统计列表中以 “J” 开头的名字数量:
    long count = names.stream()
        .filter(name -> name.startsWith("J"))
        .count();
    System.out.println("数量: " + count);
    
3. 匹配 (anyMatch / allMatch / noneMatch)
  • 检查是否有任何字符串以 “A” 开头:
    boolean exists = names.stream()
        .anyMatch(name -> name.startsWith("A"));
    System.out.println("存在: " + exists);
    
4. 查找 (findFirst / findAny)
  • 获取第一个元素:
    Optional<String> first = names.stream().findFirst();
    first.ifPresent(System.out::println);
    
5. 归约 (reduce)
  • 计算总和:
    int sum = IntStream.range(1, 6)
        .reduce(0, Integer::sum);
    System.out.println("总和: " + sum);
    

示例:完整案例演示

示例:获取学生平均成绩

import java.util.*;
import java.util.stream.*;

public class StreamExample {
    public static void main(String[] args) {
        List<Student> students = Arrays.asList(
                new Student("Alice", 85),
                new Student("Bob", 90),
                new Student("Charlie", 75)
        );

        double averageScore = students.stream()
                .mapToInt(Student::getScore)
                .average()
                .orElse(0);

        System.out.println("平均成绩: " + averageScore);
    }
}

class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    public String getName() {
        return name;
    }

    public int getScore() {
        return score;
    }
}

总结

Java 8 Stream API 提供了强大的数据操作功能,支持链式操作和多种聚合操作。熟练掌握 Stream API,可以大幅提高数据处理的效率和代码的简洁性。

4.Java Optional 类详解与使用示例

Java 8 引入了 Optional 类,旨在减少 NullPointerException 的出现,优雅地处理可能为空的值。它是一个容器类,表示一个可能包含值或为空的对象。


什么是 Optional

Optional<T> 是一个容器对象,它可能包含一个非空值,也可能为空。Optional 提供了多种方法来避免显式的 null 检查,从而减少冗余代码,提高代码的可读性和健壮性。


创建 Optional 实例的方式

1. Optional.of(T value)

  • 创建一个包含非空值的 Optional 对象。
  • 如果传入值为 null,则抛出 NullPointerException
Optional<String> optional = Optional.of("Java");

2. Optional.ofNullable(T value)

  • 创建一个可能包含 nullOptional 对象。
  • 如果传入值为 null,则返回一个空的 Optional
Optional<String> optional = Optional.ofNullable(null);  // 空的 Optional
Optional<String> optional2 = Optional.ofNullable("Hello");  // 非空的 Optional

3. Optional.empty()

  • 创建一个空的 Optional 对象。
Optional<String> emptyOptional = Optional.empty();

常用方法与示例

1. isPresent()ifPresent()

  • isPresent(): 检查值是否存在,返回布尔值。
  • ifPresent(Consumer): 如果值存在,执行传入的操作。
Optional<String> optional = Optional.of("Java");
if (optional.isPresent()) {
    System.out.println("存在值: " + optional.get());
}

optional.ifPresent(value -> System.out.println("值存在: " + value));

2. get()

  • 获取 Optional 中的值,如果为空则抛出 NoSuchElementException
Optional<String> optional = Optional.of("Java");
System.out.println(optional.get());  // 输出: Java

3. orElse(T other)

  • 如果值存在则返回该值,否则返回默认值。
Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElse("默认值"));  // 输出: 默认值

4. orElseGet(Supplier)

  • 如果值存在则返回该值,否则执行 Supplier 函数生成默认值。
Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.orElseGet(() -> "动态生成默认值"));

5. orElseThrow(Supplier)

  • 如果值存在则返回该值,否则抛出由 Supplier 提供的异常。
Optional<String> optional = Optional.ofNullable(null);
optional.orElseThrow(() -> new IllegalArgumentException("值不存在"));

6. filter(Predicate)

  • 根据条件过滤 Optional 值,如果不满足条件则返回空的 Optional
Optional<String> optional = Optional.of("Java");
optional.filter(value -> value.startsWith("J"))
        .ifPresent(System.out::println);  // 输出: Java

7. map(Function)

  • Optional 中的值执行转换操作,返回新的 Optional
Optional<String> optional = Optional.of("Java");
Optional<Integer> length = optional.map(String::length);
System.out.println("长度: " + length.orElse(0));  // 输出: 长度: 4

8. flatMap(Function)

  • map 类似,但要求返回值必须是 Optional
Optional<String> optional = Optional.of("Java");
Optional<String> upper = optional.flatMap(value -> Optional.of(value.toUpperCase()));
System.out.println(upper.orElse("空值"));  // 输出: JAVA

完整示例:用户信息管理

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        User user = new User("Alice", "alice@example.com");

        // 使用 Optional 处理可能为空的字段
        String email = Optional.ofNullable(user)
                .map(User::getEmail)
                .orElse("未提供邮箱");

        System.out.println("用户邮箱: " + email);
    }
}

class User {
    private String name;
    private String email;

    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }
}

何时使用 Optional

  • 适用场景:

    • 方法返回值可能为空。
    • 需要避免 null 检查,增强代码的可读性。
  • 不适用场景:

    • 在类的字段中使用(如实体类中的属性)。
    • 不应滥用,以避免不必要的性能开销。

总结

Optional 是处理可能为空的对象的强大工具,提供了灵活的空值处理方式,避免了繁琐的 null 检查。熟练掌握 Optional 的方法,可以编写更简洁、更健壮的 Java 代码。

标签:Java,String,Stream,System,API,println,Optional,out
From: https://blog.csdn.net/qq_36534560/article/details/144586340

相关文章

  • Javascript元编程
    元编程(Metaprogramming)是编写操作程序本身的程序的艺术,允许程序通过操作代码结构和行为来自我调整。元编程的核心是增强代码灵活性和动态性,典型的元编程功能包括拦截、修改、生成代码等文章首发博客,点击查看扫码关注公众号,查看更多优质文章引文:引用维基百科元编程的概念:......
  • 【唐叔学算法】第18天:解密选择排序的双重魅力-直接选择排序与堆排序的Java实现及性能
    引言在数据排序的世界里,选择排序是一类简单而直观的算法,它通过不断选取未排序部分中的最小(或最大)元素来逐步构建有序序列。今天,我们将深入探讨两种基于选择思想的排序方法——直接选择排序和堆排序,并提供它们的Java实现代码。此外,我们还会分析这两种排序算法的时间复杂度和......
  • 如何在PbootCMS中配置和使用API接口?
    在PbootCMS中配置和使用API接口可以让你的应用程序(如小程序、公众号、APP等)远程调取系统数据。以下是详细的配置和使用步骤:后台配置API相关参数:登录PbootCMS后台管理系统。导航到“系统设置”或“API设置”页面。在API设置中,配置以下参数:AppID:为每个应用生成一个唯一的标......
  • 6. Java自动装箱与拆箱
    1.装箱就是自动将基本数据类型转换为包装器类型(int->Integer);调用方法:Integer.valueOf(int)方法2.拆箱就是自动将包装器类型转换为基本数据类型(Integer->int);调用方法:Integer.intValue()方法在JavaSE5之前,如果要生成一个数值为10的Integer对象,必须这样执行:Integeri=newInteger......
  • 【Java项目】基于SpringBoot+Vue的租房网站
    源码获取:https://download.csdn.net/download/u011832806/89432125基于SpringBoot+Vue的租房网站开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis+Vue.js工具:IDEA/Ecilpse、Navicat、Maven租房网站通过对用户的需求进行分析,结合实际情况进行开发研究,对用户的所有需求做......
  • 证券公司API交易接口:是什么,有何用,如何获取?
    炒股自动化:申请官方API接口,散户也可以python炒股自动化(0),申请券商API接口python炒股自动化(1),量化交易接口区别Python炒股自动化(2):获取股票实时数据和历史数据Python炒股自动化(3):分析取回的实时数据和历史数据Python炒股自动化(4):通过接口向交易所发送订单Python炒股自动化(5):......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript购物商城(车之家)
    HTML+CSS+JS【购物商城】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • 大学生HTML期末大作业——HTML+CSS+JavaScript购物商城(团购)
    HTML+CSS+JS【购物商城】网页设计期末课程大作业web前端开发技术web课程设计网页规划与设计......
  • 天气查询API集成指南
    天气查询API集成指南引言在互联网和移动应用快速发展的今天,天气查询API已经成为开发人员构建各种应用程序时不可或缺的工具之一。无论是为用户提供日常出行建议、帮助农民规划农作时间,还是支持物流行业优化配送路线,实时且准确的天气信息都起着至关重要的作用。通过集成第三......
  • 基于Java的动态交通信息服务系统设计与实现
    计算机毕业设计案例Java毕业设计案例ASP.NET毕业设计案例PHP毕业设计案例微信小程序毕业设计案例基于Java的村镇社区数据管理系统基于ASPNETMVC的网站式音乐播放基于php的微信小程序在线考试系统基于Java的“free美妆榜”微信小程序【12/19/02】基于Java后台的口罩查询......