diff --git a/src/main/java/de/tototec/utils/functional/Either.java b/src/main/java/de/tototec/utils/functional/Either.java
index 03051a6..c24f9ce 100644
--- a/src/main/java/de/tototec/utils/functional/Either.java
+++ b/src/main/java/de/tototec/utils/functional/Either.java
@@ -1,153 +1,192 @@
package de.tototec.utils.functional;
import java.io.Serializable;
+import java.util.Collections;
+import java.util.List;
import java.util.NoSuchElementException;
/**
* Value class representing exactly one of two options, left or right.
- *
+ *
* This class is immutable and thus threadsafe.
*
- * @param
- * The type of the left option.
- * @param
- * The type of the right option.
+ * @param The type of the left option.
+ * @param The type of the right option.
*/
public final class Either implements Serializable {
- private static final long serialVersionUID = 1L;
-
- private final L left;
- private final R right;
- private final boolean isRight;
-
- public static Either left(final L left) {
- return new Either(left, null, false);
- }
-
- public static Either right(final R right) {
- return new Either(null, right, true);
- }
-
- /* package private */ Either(final L left, final R right, final boolean isRight) {
- this.left = left;
- this.right = right;
- this.isRight = isRight;
- if (isRight && left != null) {
- throw new IllegalArgumentException("Left value must be null");
- } else if (!isRight && right != null) {
- throw new IllegalArgumentException("Right value must be null");
- }
- }
-
- public L left() {
- if (!isRight) {
- return left;
- } else {
- throw new NoSuchElementException("Left value not defined.");
- }
- }
-
- public Optional leftOption() {
- if (!isRight) {
- return Optional.some(left);
- } else {
- return Optional.none();
- }
- }
-
- public Try leftTry() {
- if (!isRight) {
- return Try.success(left);
- } else {
- return Try.failure(new NoSuchElementException("Either.left.value on Right"));
- }
- }
-
- public R right() {
- if (isRight) {
- return right;
- } else {
- throw new NoSuchElementException("Right value not defined.");
- }
- }
-
- public Optional rightOption() {
- if (isRight) {
- return Optional.some(right);
- } else {
- return Optional.none();
- }
- }
-
- public Try rightTry() {
- if (isRight) {
- return Try.success(right);
- } else {
- return Try.failure(new NoSuchElementException("Either.right.value on Left"));
- }
- }
-
- public boolean isLeft() {
- return !isRight;
- }
-
- public boolean isRight() {
- return isRight;
- }
-
- @Override
- public String toString() {
- return isRight ? ("Right(" + right + ")") : ("Left(" + left + ")");
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + (isRight ? 1231 : 1237);
- result = prime * result + ((left == null) ? 0 : left.hashCode());
- result = prime * result + ((right == null) ? 0 : right.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (getClass() != obj.getClass()) {
- return false;
- }
- final Either, ?> other = (Either, ?>) obj;
- if (isRight != other.isRight) {
- return false;
- }
- if (isRight) {
- if (right == null) {
- if (other.right != null) {
- return false;
- }
- } else if (!right.equals(other.right)) {
- return false;
- }
- } else {
- if (left == null) {
- if (other.left != null) {
- return false;
- }
- } else if (!left.equals(other.left)) {
- return false;
- }
- }
- return true;
- }
-
- public Either swap() {
- return new Either(right, left, !isRight);
- }
+ private static final long serialVersionUID = 1L;
+
+ private final L left;
+ private final R right;
+ private final boolean isRight;
+
+ public static Either left(final L left) {
+ return new Either(left, null, false);
+ }
+
+ public static Either right(final R right) {
+ return new Either(null, right, true);
+ }
+
+ /* package private */ Either(final L left, final R right, final boolean isRight) {
+ this.left = left;
+ this.right = right;
+ this.isRight = isRight;
+ if (isRight && left != null) {
+ throw new IllegalArgumentException("Left value must be null");
+ } else if (!isRight && right != null) {
+ throw new IllegalArgumentException("Right value must be null");
+ }
+ }
+
+ public L left() {
+ if (!isRight) {
+ return left;
+ } else {
+ throw new NoSuchElementException("Left value not defined.");
+ }
+ }
+
+ public Optional leftOption() {
+ if (!isRight) {
+ return Optional.some(left);
+ } else {
+ return Optional.none();
+ }
+ }
+
+ public Try leftTry() {
+ if (!isRight) {
+ return Try.success(left);
+ } else {
+ return Try.failure(new NoSuchElementException("Either.left.value on Right"));
+ }
+ }
+
+ public R right() {
+ if (isRight) {
+ return right;
+ } else {
+ throw new NoSuchElementException("Right value not defined.");
+ }
+ }
+
+ public Optional rightOption() {
+ if (isRight) {
+ return Optional.some(right);
+ } else {
+ return Optional.none();
+ }
+ }
+
+ public Try rightTry() {
+ if (isRight) {
+ return Try.success(right);
+ } else {
+ return Try.failure(new NoSuchElementException("Either.right.value on Left"));
+ }
+ }
+
+ public boolean isLeft() {
+ return !isRight;
+ }
+
+ public boolean isRight() {
+ return isRight;
+ }
+
+ @Override
+ public String toString() {
+ return isRight ? ("Right(" + right + ")") : ("Left(" + left + ")");
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + (isRight ? 1231 : 1237);
+ result = prime * result + ((left == null) ? 0 : left.hashCode());
+ result = prime * result + ((right == null) ? 0 : right.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Either, ?> other = (Either, ?>) obj;
+ if (isRight != other.isRight) {
+ return false;
+ }
+ if (isRight) {
+ if (right == null) {
+ if (other.right != null) {
+ return false;
+ }
+ } else if (!right.equals(other.right)) {
+ return false;
+ }
+ } else {
+ if (left == null) {
+ if (other.left != null) {
+ return false;
+ }
+ } else if (!left.equals(other.left)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public Either swap() {
+ return new Either(right, left, !isRight);
+ }
+
+ public C fold(F1 l, F1 r) {
+ return isRight ? r.apply(right) : l.apply(left);
+ }
+
+ public Either map(F1 f) {
+ return isRight ? Either.right(f.apply(right)) : (Either) left;
+ }
+
+ public Either flatMap(F1> f) {
+ return isRight ? f.apply(right) : (Either) left;
+ }
+
+ public void foreach(final Procedure1 super R> f) {
+ if (isRight) {
+ f.apply(right);
+ }
+ }
+
+ public R getOrElse(final R t) {
+ return isRight ? right : t;
+ }
+
+ public R getOrElseF(final F0 f) {
+ return isRight ? right : f.apply();
+ }
+
+ public Either orElse(Either or) {
+ return isRight ? this : or;
+ }
+
+ public Either orElseF(F0> or) {
+ return isRight ? this : or.apply();
+ }
+
+ public List toList() {
+ return isRight ? Collections.singletonList(right) : Collections.emptyList();
+ }
+
}