スペース区切りの文字列を分解したものを Stream 化してみました。
イメージ的には IntStream#range みたいな使い方ができるといいなと考えました。
ダブルクォーテーションで括られたものは分解しないようにもしてみました。
KeywordStream.java
public interface KeywordStream extends BaseStream<String, Stream<String>> {
public static KeywordStream split(Optional<String> keywords) {
return new KeywordStream() {
private static final String EMPTY = "";
private static final String SEPARATOR = " (?=([^\"]*\"[^\"]*\")*[^\"]*$)";
private Stream<String> stream = Arrays.asList(keywords.orElse(EMPTY).split(SEPARATOR)).stream();
@Override
public Iterator<String> iterator() {
return stream.iterator();
}
@Override
public Spliterator<String> spliterator() {
return stream.spliterator();
}
@Override
public boolean isParallel() {
return stream.isParallel();
}
@Override
public Stream<String> sequential() {
return stream.sequential();
}
@Override
public Stream<String> parallel() {
return stream.parallel();
}
@Override
public Stream<String> unordered() {
return stream.unordered();
}
@Override
public Stream<String> onClose(Runnable closeHandler) {
return stream.onClose(closeHandler);
}
@Override
public void close() {
stream.close();
}
};
}
}
次のように使えます。
HowToUse.java
KeywordStream.split(Optional.of("I have \"a pen\"")).forEach(System.out::println);
次のような結果になります。
I
have
"a pen"
Stream.builder() を使ってもいいのですが、それだと毎回正規表現を書いたりしないといけないので、ユーティリティークラスとして作っておくと便利ですね。