Interface Either<L,R>
- Type Parameters:
L- the type of the left valueR- the type of the right value
- All Known Implementing Classes:
Either.Left, Either.Right
Either.Left or a Either.Right.
Either<L,R> is a neutral two-track type: neither side carries error
semantics. Use it when a computation legitimately returns one of two value types
without implying that one side is a failure. For error-handling use cases prefer
Result, which is semantically opinionated (Ok = success,
Err = failure) and offers richer recovery operations.
By convention, map, flatMap, and related operations act on
the right side. Use swap() to flip the sides when you need
to operate on the left.
This semantic neutrality — and the decision to keep right-biased operations without error/success connotation — is documented in ADR-007 — Either as a neutral type with no directional bias.
This interface is @NullMarked: all values — left and right — are
non-null by default.
-
Nested Class Summary
Nested Classes -
Method Summary
Modifier and TypeMethodDescriptionAppliesmapperto the right value and returns the resultingEither, leaving aEither.Leftunchanged.flatMapLeft(Function<? super L, ? extends Either<? extends L2, ? extends R>> mapper) Appliesmapperto the left value and returns the resultingEither, leaving aEither.Rightunchanged.default <T> Tdefault LgetLeft()Returns the left value.default LgetLeftOrElse(L fallback) Returns the left value if present, orfallbackif this is aEither.Right.default LgetLeftOrElseGet(Supplier<? extends L> supplier) Returns the left value if present, or the value supplied bysupplierif this is aEither.Right.default RgetRight()Returns the right value.default RgetRightOrElse(R fallback) Returns the right value if present, orfallbackif this is aEither.Left.default RgetRightOrElseGet(Supplier<? extends R> supplier) Returns the right value if present, or the value supplied bysupplierif this is aEither.Left.default booleanisLeft()Returnstrueif this is aEither.Left.default booleanisRight()Returnstrueif this is aEither.Right.static <L,R> Either <L, R> left(L value) Creates aEither.Leftinstance wrapping the given value.Maps the right value usingmapper, leaving aEither.Leftunchanged.Maps the left value usingmapper, leaving aEither.Rightunchanged.default voidExecutes one of the provided consumers depending on whether this is aEither.Leftor aEither.Right, then discards the result.static <L,R> Either <L, R> right(R value) Creates aEither.Rightinstance wrapping the given value.stream()Returns thisEitheras a single-element or emptyStream.Returns thisEitheras a single-element or emptyStreamof the left value.swap()Swaps the two sides:Either.LeftbecomesEither.Rightand vice versa.toOption()Converts thisEitherto anOption:Either.RightbecomesOption.some(Object),Either.LeftbecomesOption.none().Converts thisEitherto a standardOptional<R>.toResult()Converts thisEitherto aResult.Converts thisEitherto aTry.Converts thisEitherto aValidated.
-
Method Details
-
left
Creates aEither.Leftinstance wrapping the given value.- Type Parameters:
L- the left typeR- the right type- Parameters:
value- the non-null left value- Returns:
- an
Eithercontaining the left value - Throws:
NullPointerException- ifvalueisnull
-
right
Creates aEither.Rightinstance wrapping the given value.- Type Parameters:
L- the left typeR- the right type- Parameters:
value- the non-null right value- Returns:
- an
Eithercontaining the right value - Throws:
NullPointerException- ifvalueisnull
-
isLeft
default boolean isLeft()Returnstrueif this is aEither.Left.- Returns:
trueforLeft,falseforRight
-
isRight
default boolean isRight()Returnstrueif this is aEither.Right.- Returns:
trueforRight,falseforLeft
-
getLeft
Returns the left value.- Returns:
- the left value
- Throws:
NoSuchElementException- if this is aEither.Right
-
getRight
Returns the right value.- Returns:
- the right value
- Throws:
NoSuchElementException- if this is aEither.Left
-
getRightOrElse
Returns the right value if present, orfallbackif this is aEither.Left.- Parameters:
fallback- the non-null value returned when this isLeft- Returns:
- the right value, or
fallback - Throws:
NullPointerException- iffallbackisnull
-
getRightOrElseGet
Returns the right value if present, or the value supplied bysupplierif this is aEither.Left. The supplier is called lazily — only when this isLeft.- Parameters:
supplier- provides the fallback value; must not benulland must not returnnull- Returns:
- the right value, or the result of
supplier - Throws:
NullPointerException- ifsupplierisnullor returnsnull
-
getLeftOrElse
Returns the left value if present, orfallbackif this is aEither.Right.- Parameters:
fallback- the non-null value returned when this isRight- Returns:
- the left value, or
fallback - Throws:
NullPointerException- iffallbackisnull
-
getLeftOrElseGet
Returns the left value if present, or the value supplied bysupplierif this is aEither.Right. The supplier is called lazily — only when this isRight.- Parameters:
supplier- provides the fallback value; must not benulland must not returnnull- Returns:
- the left value, or the result of
supplier - Throws:
NullPointerException- ifsupplierisnullor returnsnull
-
fold
-
map
Maps the right value usingmapper, leaving aEither.Leftunchanged.- Type Parameters:
R2- the new right type- Parameters:
mapper- function applied to the right value; must not benulland must not returnnull- Returns:
- a new
Eitherwith the mapped right value, or the originalLeft - Throws:
NullPointerException- ifmapperisnullor returnsnull
-
mapLeft
Maps the left value usingmapper, leaving aEither.Rightunchanged.- Type Parameters:
L2- the new left type- Parameters:
mapper- function applied to the left value; must not benulland must not returnnull- Returns:
- a new
Eitherwith the mapped left value, or the originalRight - Throws:
NullPointerException- ifmapperisnullor returnsnull
-
flatMap
default <R2> Either<L,R2> flatMap(Function<? super R, ? extends Either<? extends L, ? extends R2>> mapper) Appliesmapperto the right value and returns the resultingEither, leaving aEither.Leftunchanged. This is the monadic bind for the right track.- Type Parameters:
R2- the new right type- Parameters:
mapper- function that returns anEitherfor the right value- Returns:
- the result of
mapperapplied to the right value, or the originalLeft
-
flatMapLeft
default <L2> Either<L2,R> flatMapLeft(Function<? super L, ? extends Either<? extends L2, ? extends R>> mapper) Appliesmapperto the left value and returns the resultingEither, leaving aEither.Rightunchanged. This is the monadic bind for the left track, symmetric withflatMap(Function).- Type Parameters:
L2- the new left type- Parameters:
mapper- function that returns anEitherfor the left value; must not benulland must not returnnull- Returns:
- the result of
mapperapplied to the left value, or the originalRight - Throws:
NullPointerException- ifmapperisnullor returnsnull
-
swap
Swaps the two sides:Either.LeftbecomesEither.Rightand vice versa.- Returns:
- an
Either<R,L>with the sides swapped
-
peek
-
peekLeft
-
toOption
Converts thisEitherto anOption:Either.RightbecomesOption.some(Object),Either.LeftbecomesOption.none().- Returns:
- an
Optioncontaining the right value, or empty
-
toResult
Converts thisEitherto aResult.Either.Rightmaps toResult.Ok;Either.Leftmaps toResult.Err. This is the inverse ofResult.toEither().- Returns:
- a
Result<R, L>equivalent of thisEither
-
toValidated
Converts thisEitherto aValidated.Either.Rightmaps toValidated.valid(A);Either.Leftmaps toValidated.invalid(E). Useful for bringing a neutralEitherinto the error-accumulating validation world.- Returns:
- a
Validated<L, R>equivalent of thisEither
-
toOptional
Converts thisEitherto a standardOptional<R>.Right(r)maps toOptional.of(r);Either.Leftmaps toOptional.empty(), discarding the left value.Example:
Either.<String, Integer>right(42).toOptional(); // Optional.of(42) Either.<String, Integer>left("err").toOptional(); // Optional.empty()- Returns:
- an
Optionalcontaining the right value, or empty if this isLeft
-
stream
Returns thisEitheras a single-element or emptyStream.Right(r)producesStream.of(r);Either.LeftproducesStream.empty(). Useful for integrating into stream pipelines without an explicit filter.Example:
Stream<Either<String, Integer>> eithers = ...; List<Integer> rights = eithers .flatMap(Either::stream) .toList();- Returns:
- a one-element stream of the right value, or an empty stream
-
streamLeft
Returns thisEitheras a single-element or emptyStreamof the left value.Left(l)producesStream.of(l);Either.RightproducesStream.empty(). Symmetric withstream(), which operates on the right track.Example:
Stream<Either<String, Integer>> eithers = ...; List<String> lefts = eithers .flatMap(Either::streamLeft) .toList();- Returns:
- a one-element stream of the left value, or an empty stream
-
toTry
Converts thisEitherto aTry.Right(r)maps toTry.success(r);Left(l)maps toTry.failure(leftMapper(l)).Example:
Either.<String, Integer>right(1).toTry(IllegalStateException::new); // Try.success(1) Either.<String, Integer>left("bad").toTry(IllegalStateException::new); // Try.failure(...)- Parameters:
leftMapper- function that converts the left value into aThrowable; must not benulland must not returnnull- Returns:
- a
Try<R>equivalent of thisEither - Throws:
NullPointerException- ifleftMapperisnullor returnsnull
-
match
Executes one of the provided consumers depending on whether this is aEither.Leftor aEither.Right, then discards the result. This is the terminal, side-effecting counterpart tofold(Function, Function).Example:
either.match( left -> log.warn("Left: {}", left), right -> process(right) );- Parameters:
onLeft- consumer executed when this isLeft; must not benullonRight- consumer executed when this isRight; must not benull- Throws:
NullPointerException- ifonLeftoronRightisnull
-