Skip to content

Instantly share code, notes, and snippets.

@yoshi389111
Last active December 6, 2015 01:45
Show Gist options
  • Save yoshi389111/53dfab68d1a037fc85cf to your computer and use it in GitHub Desktop.
Save yoshi389111/53dfab68d1a037fc85cf to your computer and use it in GitHub Desktop.
throwable stream / optional class
/*
* Consumer2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.function.Consumer;
@FunctionalInterface
public interface Consumer2<T, E extends Exception> extends Consumer<T> {
@Override
default void accept(T t) {
try {
accept0(t);
} catch (Exception e) {
Stream2.sneakyThrows(e);
}
}
void accept0(T t) throws E;
}
/*
* Function2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.function.Function;
@FunctionalInterface
public interface Function2<T, R, E extends Exception> extends Function<T, R> {
@Override
default R apply(T t) {
try {
return apply0(t);
} catch (Exception e) {
Stream2.sneakyThrows(e);
// NOTREACHED
throw new AssertionError();
}
}
R apply0(T t) throws E;
}
/*
* Optional2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;
/** 例外を投げられる Optional もどき */
public final class Optional2<T> {
/** 空の Optional2 */
private static final Optional2<?> EMPTY = new Optional2<>(null);
/** 値 */
private final T value;
/** コンストラクタ */
private Optional2(T value) {
this.value = value;
}
/** null でない Optional2 を生成 */
public static <T> Optional2<T> of(T value) {
Objects.requireNonNull(value);
return new Optional2<>(value);
}
/** 空の Optional2 を取得 */
public static <T> Optional2<T> empty() {
@SuppressWarnings("unchecked")
Optional2<T> t = (Optional2<T>) EMPTY;
return t;
}
/** Optional から Optional2 を生成 */
public static <T> Optional2<T> of(Optional<T> opt) {
Objects.requireNonNull(opt);
if (opt.isPresent()) {
return new Optional2<>(opt.get());
} else {
return empty();
}
}
/** null の可能性もある Optional2 を生成 */
public static <T> Optional2<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
/** 値を取得. 空の場合には例外 */
public T get() {
if (value == null) {
throw new NoSuchElementException();
}
return value;
}
/** 値がある場合に真 */
public boolean isPresent() {
return value != null;
}
/** 値がある場合には処理を行う */
public <E extends Exception> void ifPresent(Consumer2<? super T, E> consumer) throws E {
if (value != null) {
consumer.accept(value);
}
}
/** フィルター */
public <E extends Exception> Optional2<T> filter(Predicate2<? super T, E> predicate) throws E {
Objects.requireNonNull(predicate);
if (!isPresent()) {
return this;
} else {
return predicate.test(value) ? this : empty();
}
}
/** 値がある場合に変換を行う */
public <U, E extends Exception> Optional2<U> map(Function2<? super T, ? extends U, E> mapper) throws E {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional2.ofNullable(mapper.apply(value));
}
}
/** 値がある場合に変換を行う */
public <U, E extends Exception> Optional2<U> flatMap(Function2<? super T, Optional2<U>, E> mapper) throws E {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Objects.requireNonNull(mapper.apply(value));
}
}
/** 値がある場合に変換を行う */
public <U, E extends Exception> Optional2<U> flatMap1(Function2<? super T, Optional<U>, E> mapper) throws E {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return of(Objects.requireNonNull(mapper.apply(value)));
}
}
/** 値がなければ、代わりの値を返す */
public T orElse(T other) {
return value != null ? value : other;
}
/** 値がなければ、代わりの値を求める */
public <E extends Exception> T orElseGet(Supplier2<? extends T, E> other) throws E {
return value != null ? value : other.get();
}
/** 値がなければ例外を投げる */
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
// これは Supplier2 にしなくていいよね?
throw exceptionSupplier.get();
}
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof Optional2) {
Optional2<?> that = (Optional2<?>) other;
return Objects.equals(this.value, that.value);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(value);
}
@Override
public String toString() {
return value != null
? String.format("Optional2[%s]", value)
: "Optional2.empty";
}
}
/*
* Optional2Test.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.io.IOException;
public class Optional2Test {
public static void main(String[] args) {
// チェック例外を投げないならは、try - catch は不要
String s1 = Optional2.of("Charlie")
.map(s -> s + s)
.orElse("null");
System.out.println(s1);
// チェック例外を外側でキャッチ
try {
Optional2<String> opt = Optional2.of("Charlie");
String s2 = opt.map(Optional2Test::method)
.orElse("null");
System.out.println(s2);
} catch (IOException e) {
e.printStackTrace();
}
}
private static String method(String name) throws IOException {
if (name.startsWith("C")) {
// チェック例外を投げる
throw new IOException(name);
} else {
System.out.println(name);
return name;
}
}
}
/*
* Predicate2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.function.Predicate;
@FunctionalInterface
public interface Predicate2<T, E extends Exception> extends Predicate<T> {
@Override
default boolean test(T t) {
try {
return test0(t);
} catch (Exception e) {
Stream2.sneakyThrows(e);
// NOTREACHED
throw new AssertionError();
}
}
boolean test0(T t) throws E;
}
/*
* Stream2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.Comparator;
import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
import java.util.function.ToIntFunction;
import java.util.function.ToLongFunction;
import java.util.stream.Collector;
import java.util.stream.DoubleStream;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class Stream2<E> implements AutoCloseable {
/** 元となる Stream */
private final Stream<E> base;
/** Stream から Stream2 を生成 */
public static <E> Stream2<E> of(Stream<E> base) {
return new Stream2<E>(base);
}
/** コンストラクタ */
private Stream2(Stream<E> base) {
this.base = Objects.requireNonNull(base);
}
/** クローズ処理の登録 */
public Stream2<E> onClose(Runnable closeHandler) {
base.onClose(closeHandler);
return this;
}
/** クローズ */
@Override
public void close() {
base.close();
}
/** フィルタ */
public <T extends Exception> Stream2<E> filter(Predicate2<? super E, T> predicate) throws T {
return of(base.filter(predicate));
}
/** 変換 */
public <R, T extends Exception> Stream2<R> map(Function2<? super E, ? extends R, T> mapper) throws T {
return of(base.map(mapper));
}
/** int変換 */
public IntStream mapToInt(ToIntFunction<? super E> mapper) {
// めんどくさいので省略
return base.mapToInt(mapper);
}
/** long変換 */
public LongStream mapToLong(ToLongFunction<? super E> mapper) {
// めんどくさいので省略
return base.mapToLong(mapper);
}
/** double変換 */
public DoubleStream mapToDouble(ToDoubleFunction<? super E> mapper) {
// めんどくさいので省略
return base.mapToDouble(mapper);
}
/** 変換 */
public <R, T extends Exception> Stream2<R> flatMap(Function2<? super E, ? extends Stream<? extends R>, T> mapper)
throws T {
return of(base.flatMap(mapper));
}
/** int変換 */
public <T extends Exception> IntStream flatMapToInt(Function2<? super E, ? extends IntStream, T> mapper) throws T {
// めんどくさいので省略
return base.flatMapToInt(mapper);
}
/** long変換 */
public <T extends Exception> LongStream flatMapToLong(Function2<? super E, ? extends LongStream, T> mapper)
throws T {
// めんどくさいので省略
return base.flatMapToLong(mapper);
}
/** double変換 */
public <T extends Exception> DoubleStream flatMapToDouble(Function2<? super E, ? extends DoubleStream, T> mapper)
throws T {
// めんどくさいので省略
return base.flatMapToDouble(mapper);
}
/** 処理 */
public <T extends Exception> void forEach(Consumer2<? super E, T> action) throws T {
base.forEach(action);
}
/** 処理 */
public <T extends Exception> void forEachOrdered(Consumer2<? super E, T> action) throws T {
base.forEachOrdered(action);
}
/** 配列化 */
public Object[] toArray() {
return base.toArray();
}
/** 配列化 */
public <A> A[] toArray(IntFunction<A[]> generator) {
return base.toArray(generator);
}
/** まとめる */
public E reduce(E identity, BinaryOperator<E> accumulator) {
// めんどくさいので省略
return base.reduce(identity, accumulator);
}
/** まとめる */
public Optional2<E> reduce(BinaryOperator<E> accumulator) {
// めんどくさいので省略
return Optional2.of(base.reduce(accumulator));
}
/** まとめる */
public <U> U reduce(U identity, BiFunction<U, ? super E, U> accumulator, BinaryOperator<U> combiner) {
// めんどくさいので省略
return base.reduce(identity, accumulator, combiner);
}
/** まとめる */
public <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super E> accumulator, BiConsumer<R, R> combiner) {
// めんどくさいので省略
return base.collect(supplier, accumulator, combiner);
}
/** まとめる */
public <R, A> R collect(Collector<? super E, A, R> collector) {
return base.collect(collector);
}
/** 最小値 */
public Optional2<E> min(Comparator<? super E> comparator) {
return Optional2.of(base.min(comparator));
}
/** 最大値 */
public Optional2<E> max(Comparator<? super E> comparator) {
return Optional2.of(base.max(comparator));
}
/** カウント */
public long count() {
return base.count();
}
/** 1つでもマッチするか */
public <T extends Exception> boolean anyMatch(Predicate2<? super E, T> predicate) throws T {
return base.anyMatch(predicate);
}
/** すべてマッチするか */
public <T extends Exception> boolean allMatch(Predicate2<? super E, T> predicate) throws T {
return base.allMatch(predicate);
}
/** 1つもマッチしないか */
public <T extends Exception> boolean noneMatch(Predicate2<? super E, T> predicate) throws T {
return base.noneMatch(predicate);
}
/** 先頭の1つを返す */
public Optional2<E> findFirst() {
return Optional2.of(base.findFirst());
}
/** どれか1つ返す */
public Optional2<E> findAny() {
return Optional2.of(base.findAny());
}
/** 無理やり例外を投げる */
public static <E extends Exception> void sneakyThrows(Exception exception) throws E {
@SuppressWarnings("unchecked")
E e = (E) exception;
throw e;
}
}
/*
* Stream2Test.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class Stream2Test {
public static void main(String[] args) {
List<String> names = Arrays.asList("Alfa", "Bravo", "Charlie");
// チェック例外を投げないならは、try - catch は不要
Stream2<String> stream1 = Stream2.of(names.stream());
stream1.forEach(name -> {
System.out.println(name);
});
// チェック例外を外側でキャッチ
try {
Stream2<String> stream2 = Stream2.of(names.stream());
stream2.forEach(name -> {
method(name);
});
} catch (IOException e) {
e.printStackTrace();
}
}
private static String method(String name) throws IOException {
if (name.startsWith("C")) {
throw new IOException(name);
} else {
System.out.println(name);
return name;
}
}
}
/*
* Supplier2.java
* Copyright (C) 2015, SATO_Yoshiyuki
* This software is released under the MIT License.
* http://opensource.org/licenses/mit-license.php
*/
import java.util.function.Supplier;
@FunctionalInterface
public interface Supplier2<T, E extends Exception> extends Supplier<T> {
@Override
default T get() {
try {
return get0();
} catch (Exception e) {
Stream2.sneakyThrows(e);
// NOTREACHED
throw new AssertionError();
}
}
T get0() throws E;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment