Create a gist now

Instantly share code, notes, and snippets.

import java.util.Optional;
import java.util.stream.Collector;
import java.util.stream.Collectors;
public class StreamUtils {
/**
* (0でなく2以上でもない)ちょうど1つの要素を持っているリストから要素を取り出します.
* 要素数がちょうど1でない場合, 例外を送出します.
* collect終端操作の引数に指定します.
*
* @return 取り出した要素
* @throws IllegalStateException
* 要素数が1ではなかった
* @see http://stackoverflow.com/a/22695031/4506703
*/
public static <T> Collector <T, ?, T> single() {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> {
if (list.size() == 1) {
return list.get(0);
}
throw new IllegalStateException("unexpected number of elements: " + list.size());
});
}
/**
* 0または1つの要素を持っているリストから要素を取り出します.
* 要素数が2以上の場合, 例外を送出します.
* collect終端操作の引数に指定します.
*
* @return 取り出した要素
* @throws IllegalStateException
* 要素数が2以上だった
*/
public static <T> Collector <T, ?, Optional <T>> option() {
return Collectors.collectingAndThen(
Collectors.toList(),
list -> {
final int size = list.size();
if (size == 0) {
return Optional.empty();
} else if (size == 1) {
return Optional.of(list.get(0));
}
throw new IllegalStateException("unexpected number of elements: " + list.size());
});
}
/**
* キャスト可能なものはキャストし, そうでないものは無視します.
* <code>list.stream().flatMap(e -> castIfCan(e, BigDecimal.class))</code>
* のような形で使用することを想定しています.
*
* @param <T>
* キャスト先の型
* @param o
* 判定対象
* @param clazz
* このクラスにキャスト可能かどうかを判定します.
* @return キャスト可能だった場合には要素が1入ったストリーム, 不能だった場合には空ストリーム.
*/
public static <T> Stream<T> castIfCan(final Object o, final Class<T> clazz) {
if (clazz.isInstance(o)) {
return Stream.of(clazz.cast(o));
}
return Stream.empty();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment