Gatherers 的方法

windowFixed(windowSize)

将 Stream 的元素分组到固定大小的窗口中。返回的每个窗口 List 是不可修改的。

import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G1 {
    public static void main(String[] args) {
        List<List<Integer>> windows =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8).gather(Gatherers.windowFixed(3)).toList();
        System.out.println(windows);
		// 窗口不能修改,会抛异常 UnsupportedOperationException
        windows.get(0).add(1);
    }
}

输出:

[[1, 2, 3], [4, 5, 6], [7, 8]]
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:142)
	at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:147)
	at org.example.stream.G1.main(G1.java:13)

windowSliding(windowSize)

滑动窗口

import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G2 {
    public static void main(String[] args) {
        List<List<Integer>> windows2 =
                Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowSliding(2)).toList();
        System.out.println(windows2);

        List<List<Integer>> windows6 =
                Stream.of(1,2,3,4,5,6,7,8).gather(Gatherers.windowSliding(6)).toList();
        System.out.println(windows6);
    }
}

输出

[[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8]]
[[1, 2, 3, 4, 5, 6], [2, 3, 4, 5, 6, 7], [3, 4, 5, 6, 7, 8]]

fold(initial, folder)

public static <T, R> Gatherer<T, ?, R> fold(
        Supplier<R> initial,
        BiFunction<? super R, ? super T, ? extends R> folder);

类似 reduce 的功能,只会将最后的结果发送到 Stream 的下一个阶段,伪代码如下:

public static <T, R> void fold(Supplier<R> initial, BiFunction<? super R, ? super T, ? extends R> folder) {

    List<T> elements = null;
    R value = initial.get();

    for (T e : elements) {
        value = folder.apply(value, e);
    }

    // 将 value 发送到 Stream 的下一个阶段
}
import java.util.List;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G3 {
    public static void main(String[] args) {
        Optional<String> numberString =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.fold(() -> "", (string, number) -> string + number)
                        )
                        .findFirst();
        System.out.println(numberString);
    }
}

// 输出
Optional[123456789]

scan(initial, scanner)

public static <T, R> Gatherer<T, ?, R> scan(
        Supplier<R> initial,
        BiFunction<? super R, ? super T, ? extends R> scanner);

使用提供的 scanner 执行 Prefix Scan – 增量累积。从 initial 获得的初始值开始,通过将 scanner 应用于当前值和下一个输入元素来获取每个后续值,并将每个后续值发送到 Stream 的下一个阶段。

foldscan 的参数是相同的,区别在于 fold 只会将最后的结果发送到下一个阶段,而 scan 会将每个中间结果都发送到下一个阶段。伪代码:

public static <T, R> void scan(Supplier<R> initial, BiFunction<? super R, ? super T, ? extends R> folder) {

    List<T> elements = null;
    R value = initial.get();

    for (T e : elements) {
        value = folder.apply(value, e);
        // 将 value 发送到 Stream 的下一个阶段
    }
}
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G4 {
    public static void main(String[] args) {
        List<String> numberStrings =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.scan(() -> "", (string, number) -> string + number)
                        )
                        .toList();
        System.out.println(numberStrings);
    }
}
// 输出
[1, 12, 123, 1234, 12345, 123456, 1234567, 12345678, 123456789]

mapConcurrent(mapConcurrent, mapper)

使用虚拟线程以配置的最大并发级数执行与 Stream#map 方法类似的功能。此操作将保留流的顺序。

public static <T, R> Gatherer<T,?,R> mapConcurrent(
        final int maxConcurrency,
        final Function<? super T, ? extends R> mapper) 
import java.util.List;
import java.util.stream.Gatherers;
import java.util.stream.Stream;

public class G5 {
    public static void main(String[] args) {
        List<Integer> numberStrings =
                Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9)
                        .gather(
                                Gatherers.mapConcurrent(3, (element) -> {
                                    System.out.println(Thread.currentThread().isVirtual());
                                    return element * element;
                                })
                        )
                        .toList();
        System.out.println(numberStrings);
    }
}

输出:可以看出确实使用了虚拟线程

true
true
true
true
true
true
true
true
true
[1, 4, 9, 16, 25, 36, 49, 64, 81]
<think>嗯,用户让我介绍一下Java的最新特性。我现在得先回想一下Java最近的版本情况。Java现在每半年发布一次新版本,所以最新版本应该是Java 22,发布于2024年3月。不过,可能需要确认一下,因为用户可能不太清楚具体的版本号,可能他们所说的“最新”是指最近几个版本的主要更新。 首先,我应该按版本梳理特性,比如从Java 17开始,因为那是长期支持(LTS)版本,之后是18、19、20、21、22。用户可能更关注LTS版本的变化,比如Java 21是最近的LTS,所以它的特性更为重要。 然后需要列出每个版本的主要特性。比如Java 17有密封类、模式匹配switch预览等。Java 19引入了虚拟线程的预览,这是协程的重要特性。Java 21正式推出虚拟线程,还有字符串模板、序列化集合等。Java 22可能有一些新特性,比如未命名变量、字符串模板的二次预览等。 需要注意用户可能对某些术语不太了解,比如虚拟线程、模式匹配等,需要适当解释,但保持简洁。同时,要避免过于技术化的术语,用中文通俗说明。 另外,用户可能想知道这些特性带来的好处,比如性能提升、代码简化等。例如,虚拟线程如何提高并发性能,模式匹配如何简化代码结构。 还需要检查是否有遗漏的重要特性,比如JVM的改进,或者API的更新,比如新的集合方法。比如Java 21引入的SequencedCollection接口,这对处理有序集合很有帮助。 要确保信息准确,比如确认各个特性对应的版本号是否正确,避免错误。例如,未命名变量和模式是在Java 21还是22引入的?可能需要查证,Java 21确实有未命名变量的预览,而Java 22可能进一步更新。 最后,结构要清晰,分版本说明,每个版本列出几个关键特性,并简要解释其作用和优势。这样用户能逐步了解各个版本的变化,以及最新版本的亮点。</think>以下为Java最新特性介绍(截至2024年6月),按版本递进结构说明: --- ### **一、Java 21(2023年9月发布,LTS版本)** #### 核心特性 1. **虚拟线程(正式版)** 轻量级线程实现,显著提升并发性能 示例:`Thread.startVirtualThread(() -> {...})` 2. **字符串模板(预览)** 增强字符串拼接安全性 示例:`String info = STR."User \{name} is \{age} years old";` 3. **序列化集合API** 新增`SequencedCollection`接口,优化有序集合操作 支持直接获取首尾元素:`list.getFirst()`, `list.getLast()` 4. **未命名模式与变量(预览)** 用`_`符号忽略未使用的变量 示例:`if (obj instanceof Point(_, int y)) { ... }` --- ### **二、Java 22(2024年3月发布)** #### 重要更新 1. **未命名变量与模式(二次预览)** 扩展至`catch`块:`try {...} catch(Exception _)` 2. **字符串模板(第二次预览)** 新增自定义模板处理器功能 3. **Foreign Function API(正式版)** 原生支持非Java代码调用 示例:直接调用C语言库函数 4. **Stream Gatherers(预览)** 增强流处理能力,支持自定义中间操作 示例:`.gather(Gatherers.windowSliding(3))` --- ### **三、Java 17(2021年LTS)关键延续特性** 1. **密封类(Sealed Classes)** 精确控制类继承关系 示例:`public sealed class Shape permits Circle, Square` 2. **模式匹配Switch(正式版)** 支持类型匹配和空值处理 示例: ```java switch (obj) { case String s -> System.out.println(s.length()); case null -> System.out.println("null"); default -> {} } ``` --- ### **四、开发者价值** 1. **性能提升** 虚拟线程可支持百万级并发(对比传统线程提升10倍+) 2. **代码简洁度** 模式匹配使代码量减少约30% 3. **安全性增强** 字符串模板有效预防SQL注入等风险 建议生产环境优先选择Java 21 LTS版本,新项目可尝试Java 22的非预览特性。可通过`jshell`工具快速体验新语法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值