Last active
December 6, 2015 01:45
-
-
Save yoshi389111/53dfab68d1a037fc85cf to your computer and use it in GitHub Desktop.
throwable stream / optional class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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"; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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