当前位置:   article > 正文

8个你必须知道的Java8新特性,让你的代码变得优雅!

java8
Java 8 是一次重大的发行版更新,引入了大量新特性和改进,以下是 Java 8 的主要特性:


在这里插入图片描述

1.Lambda 表达式

Lambda 允许在代码中直接定义匿名函数,简化了对函数式编程的支持。

// Lambda 表达式示例
List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
nums.stream()
    .filter(num -> num % 2 == 0) // 过滤偶数
    .map(num -> num * 2) // 将每个元素乘以 2
    .forEach(System.out::println); // 打印结果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
2.Stream API

通过 Stream API 可以轻松处理集合和数组等数据结构,提高了代码的可读性和可维护性。以下是Stream API中常用的方法:

  • filter(Predicate predicate):过滤出所有符合条件的元素。

  • map(Function function):将元素转换为另一种类型。

  • flatMap(Function function):将嵌套的多个流扁平化成一个流。

  • distinct():去除重复元素。

  • sorted():排序。

  • boxed:将基本数据类型转换为对应的包装类类型。

  • peek(Consumer action):对每个元素执行指定的操作。

  • limit(long maxSize):限制元素数量。

  • skip(long n):跳过前 n 个元素。

  • forEach(Consumer action):对每个元素执行指定的操作。

  • count():计数。

  • reduce(BinaryOperator accumulator):将所有元素归约成一个结果。

  • collect(Collector collector):收集结果到一个集合中。

  • allMatch(Predicate predicate):判断是否所有元素都符合给定条件。

  • anyMatch(Predicate predicate):判断是否任何一个元素符合给定条件。

  • noneMatch(Predicate predicate):判断是否没有任何元素符合给定条件。

  • findFirst():返回第一个元素。

  • findAny():返回任意一个元素。

  • 这些操作可以通过链式调用的方式进行组合,形成一个完整的流处理链。如下是一个简单的例子:

    List<String> list = Arrays.asList("apple", "banana", "orange", "peach");long count = list.stream()  // 将 List 转换为 Stream
                     .filter(str -> str.startsWith("a"))  // 过滤出以 a 开头的字符串
                     .map(String::toUpperCase)  // 转换为大写
                     .count();  // 统计数量System.out.println(count);  // 输出结果:1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    3.Date/Time API

    在 Java 8 中引入了全新的日期时间处理类库,使得处理日期时间变得更加方便和易于理解。以下是 java.time 包中最重要的一些类:

    • LocalDate:表示日期,如 2022 年 5 月 15 日。
    • LocalTime:表示时间,如 13:45:30。
    • LocalDateTime:代表日期和时间,比如 2022 年 5 月 15 日 13:45:30。
    • ZonedDateTime:代表带有时区的日期时间,在上述所有日期时间类型的基础上,还提供了时区信息。
    • Duration:在两个时间点之间表示时间量。
    • Period:在两个日期之间表示天、周、月或年的数量。
    • DateTimeFormatter:可以将日期时间对象按照指定的格式进行格式化或者解析。
    • 以下是使用 Java 8 新的日期时间 API 的一些示例代码:
    // 创建 LocalDate 对象,表示当前日期
    LocalDate localDate = LocalDate.now();// 创建 LocalTime 对象,表示下午 2:30 这个时间点
    LocalTime localTime = LocalTime.of(14, 30, 0);// 创建 LocalDateTime 对象,表示 2022 年 6 月 1 日上午 12:30 这个日期时间。
    LocalDateTime localDateTime = LocalDateTime.of(2022, Month.JUNE, 1, 12, 30);// 在当前日期时间上加上一小时
    localDateTime = localDateTime.plusHours(1L);// 创建 Duration 对象,并计算两个时间点之间的时间量
    Duration duration = Duration.between(localTime, LocalTime.now());// 使用 DateTimeFormatter 对象对日期时间进行格式化
    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    String formattedDateTime = localDateTime.format(dateTimeFormatter);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    4.接口中的默认方法:

    ​ 允许在接口中添加默认方法的实现,大大提高了接口的灵活性和扩展性。需要注意的是,这些接口默认方法并不是强制实现的,也可以被继承类或实现类所覆盖和重写。但在没有其他需求时,通过使用默认方法,可以大幅简化代码,并保证 API 的向后兼容性。如下Collection 接口中新增的 stream()、parallelStream() 和 removeIf() 等默认方法

    public interface Collection<E> extends Iterable<E> {
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
        default Stream<E> parallelStream() {
            return StreamSupport.stream(spliterator(), true);
        }
        default boolean removeIf(Predicate<? super E> filter) {
            Objects.requireNonNull(filter);
            boolean removed = false;
            final Iterator<E> each = iterator();
            while (each.hasNext()) {
                if (filter.test(each.next())) {
                    each.remove();
                    removed = true;
                }
            }
            return removed;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    5.函数式接口

    函数式接口非常适合用于Lambda表达式和方法引用,因为它们可以将这些功能作为参数传递给方法或返回值,从而使代码更简洁、更具可读性。许多Java内置的函数式接口都在java.util.function包中定义,其中几个常用的接口如下:

    Function:接受一个参数并产生结果的函数。

    // 接收一个字符串类型参数并返回对应整数长度值
    Function<String, Integer> stringToLength = str -> str.length();
    System.out.println(stringToLength.apply("Hello World!"));
    // 输出结果:12
    
    • 1
    • 2
    • 3
    • 4

Predicate: 接受一个参数并返回一个布尔值,表示断言函数。

// 判断一个数字是否是奇数
Predicate<Integer> isOdd = number -> number % 2 != 0;
System.out.println(isOdd.test(5));
// 输出结果:true
  • 1
  • 2
  • 3
  • 4

Consumer`:接受一个参数不返回结果,表示消费者函数。

// 输出一个字符串的大写形式
Consumer<String> printStringInUpperCase = str -> System.out.println(str.toUpperCase());
printStringInUpperCase.accept("hello world!");
// 输出结果:HELLO WORLD!

  • 1
  • 2
  • 3
  • 4
  • 5

Supplier:提供一个无参构造函数,返回任意类型结果。

// 产生随机数
Supplier<Integer> randomIntegerSupplier = () -> (int) (Math.random() * 100);
System.out.println(randomIntegerSupplier.get());
// 输出结果:一个0~99之间的随机整数
  • 1
  • 2
  • 3
  • 4
6.方法引用(:声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop】
推荐阅读