[解決済み] ScalaのEitherに相当するものはJava 8にありますか?
2023-06-05 02:30:57
質問
まるで
java.util.Optional<T>
が(多少)Scalaの
Option[T]
型と同等ですが,Scala の
Either[L, R]
?
どのように解決するのですか?
には
Either
型がないので、自分で作るか、サードパーティのライブラリを使う必要があります。
このような機能を構築するには、新しい
Optional
型を使ってそのような機能を構築することができます(ただし、この回答の最後を読んでください)。
final class Either<L,R>
{
public static <L,R> Either<L,R> left(L value) {
return new Either<>(Optional.of(value), Optional.empty());
}
public static <L,R> Either<L,R> right(R value) {
return new Either<>(Optional.empty(), Optional.of(value));
}
private final Optional<L> left;
private final Optional<R> right;
private Either(Optional<L> l, Optional<R> r) {
left=l;
right=r;
}
public <T> T map(
Function<? super L, ? extends T> lFunc,
Function<? super R, ? extends T> rFunc)
{
return left.<T>map(lFunc).orElseGet(()->right.map(rFunc).get());
}
public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc)
{
return new Either<>(left.map(lFunc),right);
}
public <T> Either<L,T> mapRight(Function<? super R, ? extends T> rFunc)
{
return new Either<>(left, right.map(rFunc));
}
public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc)
{
left.ifPresent(lFunc);
right.ifPresent(rFunc);
}
}
使用例です。
new Random().ints(20, 0, 2).mapToObj(i -> (Either<String,Integer>)(i==0?
Either.left("left value (String)"):
Either.right(42)))
.forEach(either->either.apply(
left ->{ System.out.println("received left value: "+left.substring(11));},
right->{ System.out.println("received right value: 0x"+Integer.toHexString(right));}
));
レトロスペクティブでは
Optional
に基づく解決策は、どちらかというと学術的な例であって、推奨されるアプローチではありません。問題のひとつは、その扱いが
null
を "空 "として扱うことで、"どちらか "の意味と矛盾しています。
次のコードでは
Either
を考慮した
null
が可能な値であっても、厳密には左右のどちらかになります。
null
:
abstract class Either<L,R>
{
public static <L,R> Either<L,R> left(L value) {
return new Either<L,R>() {
@Override public <T> T map(Function<? super L, ? extends T> lFunc,
Function<? super R, ? extends T> rFunc) {
return lFunc.apply(value);
}
};
}
public static <L,R> Either<L,R> right(R value) {
return new Either<L,R>() {
@Override public <T> T map(Function<? super L, ? extends T> lFunc,
Function<? super R, ? extends T> rFunc) {
return rFunc.apply(value);
}
};
}
private Either() {}
public abstract <T> T map(
Function<? super L, ? extends T> lFunc, Function<? super R, ? extends T> rFunc);
public <T> Either<T,R> mapLeft(Function<? super L, ? extends T> lFunc) {
return this.<Either<T,R>>map(t -> left(lFunc.apply(t)), t -> (Either<T,R>)this);
}
public <T> Either<L,T> mapRight(Function<? super R, ? extends T> lFunc) {
return this.<Either<L,T>>map(t -> (Either<L,T>)this, t -> right(lFunc.apply(t)));
}
public void apply(Consumer<? super L> lFunc, Consumer<? super R> rFunc) {
map(consume(lFunc), consume(rFunc));
}
private <T> Function<T,Void> consume(Consumer<T> c) {
return t -> { c.accept(t); return null; };
}
}
を厳密に拒否するように変更するのは簡単です。
null
を拒否するように変更するのは簡単です。
Objects.requireNonNull(value)
を挿入するだけです。同様に、空のどちらかのサポートを追加することも想像がつくでしょう。
関連
-
実行中にEclipseがポップアップする A Java Exception has occurred
-
Java基礎編 - オブジェクト指向
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaでメモリーリークを発生させるにはどうしたらいいですか?
-
[解決済み] JavaでArrayListではなくLinkedListを使用するのはいつですか?
-
[解決済み] JavaBeanとは何ですか?
-
[解決済み] Javaで汎用配列を作成する方法は?
-
[解決済み】JSP 2を使用して、JSPファイル内のJavaコードを回避するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
NullPointerException - java.lang.
-
undefined[sonar] sonar:デフォルトのスキャンルール
-
Eclipse の問題 アクセス制限。タイプ 'jfxrt' はAPI解決されていません。
-
java.sql.SQLException: executeQuery()でデータ操作文を発行できません。
-
プロジェクトの依存関係を解決できない。
-
Junitのユニットテストエラー
-
Server Tomcat v9.0 Server at localhost の起動に失敗しました。
-
Web Project JavaでPropertiesファイルを読み込むと、「指定されたファイルがシステムで見つかりません」というソリューションが表示されます。
-
Java基礎 - マッピングとQ/A
-
[解決済み】Java 8のゲッターはオプションの型を返すべきですか?