You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK中是否存在支持hasNext/next组合的便捷Iterator或Stream工厂?

Great question! Unfortunately, the JDK doesn't include a built-in factory method that directly takes separate hasNext and next suppliers to create an Iterator or Stream—which is a bit surprising given how common this use case is with Matcher. But don't worry, there are clean, JDK-only ways to avoid that verbose anonymous class.

1. Wrap a tiny custom utility class (cleanest approach)

Since you can't use third-party libraries, write a simple reusable utility to encapsulate the anonymous Iterator logic. This is one-time code and makes your main code much cleaner:

// Put this in a utility class in your project
public class IteratorFactories {
    public static <T> Iterator<T> from(BooleanSupplier hasNext, Supplier<T> next) {
        return new Iterator<>() {
            @Override
            public boolean hasNext() {
                return hasNext.getAsBoolean();
            }

            @Override
            public T next() {
                return next.get();
            }
        };
    }
}

Now you can create your Iterator and Stream in concise lines:

Iterator<String> matchIterator = IteratorFactories.from(matcher::find, matcher::group);
Stream<String> matchStream = StreamSupport.stream(
    Spliterators.spliteratorUnknownSize(matchIterator, Spliterator.ORDERED),
    false // sequential stream; set to true for parallel if needed
);

2. Use Stream.iterate (Java 9+)

If you're on Java 9 or later, you can leverage the overload of Stream.iterate that takes a predicate to terminate the stream. It's a slight hack since we use a dummy initial value, but it avoids writing any custom classes:

Stream<String> matchStream = Stream.iterate(
        null, // Dummy initial value
        ignored -> matcher.find(), // Terminate when find() returns false
        ignored -> matcher.group() // Get the match for each iteration
    )
    .skip(1); // Skip the dummy initial null value

3. Direct Spliterator creation (no utility class, minimal boilerplate)

If you don't want to add a utility class, you can wrap the anonymous Iterator directly into a Spliterator to get a Stream—though this doesn't save much code over your original approach, it's still fully JDK-native:

Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(
    new Iterator<>() {
        @Override
        public boolean hasNext() {
            return matcher.find();
        }

        @Override
        public String next() {
            return matcher.group();
        }
    },
    Spliterators.ORDERED | Spliterators.NONNULL
);

Stream<String> matchStream = StreamSupport.stream(spliterator, false);

Why no built-in JDK factory?

The core reason is that Iterator has two abstract methods (hasNext and next), so it's not a functional interface—you can't construct it with a single lambda. The JDK hasn't added a dedicated factory for this specific combination of suppliers, which is why third-party libraries like Guava have their own versions (but you can't use those here). Your custom utility class fills that gap perfectly, and it's trivial to maintain.

内容的提问来源于stack exchange,提问作者Marnes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:20:33