fork download
  1. /* package whatever; // don't place package name! */
  2.  
  3.  
  4. import java.util.*;
  5. import java.util.function.*;
  6.  
  7.  
  8. /* Name of the class has to be "Main" only if the class is public. */
  9. class Ideone
  10. {
  11. public static void main (String[] args) throws java.lang.Exception
  12. {
  13. BiOptional.of("Some thing", "Some other thing")
  14. .mapLeft(String::length)
  15. .mapRight(String::length)
  16. .mergeToInt(Integer::sum)
  17. .ifPresent(System.out::println);
  18. }
  19. }
  20.  
  21. final class BiOptional<L, R>{
  22.  
  23. private static final BiOptional<?, ?> EMPTY = new BiOptional<>(null, null, false);
  24.  
  25. private final L left;
  26. private final R right;
  27. private final boolean present;
  28.  
  29. private BiOptional(L left, R right, boolean present){
  30. this.left = left;
  31. this.right = right;
  32. this.present = present;
  33. }
  34.  
  35. public static <L, R> BiOptional<L, R> empty(){
  36. @SuppressWarnings("unchecked")
  37. final BiOptional<L, R> empty = (BiOptional<L, R>) EMPTY;
  38. return empty;
  39. }
  40.  
  41. public static <L, R> BiOptional<L, R> of(L left, R right){
  42. return new BiOptional<>(
  43. Objects.requireNonNull(left),
  44. Objects.requireNonNull(right),
  45. true
  46. );
  47. }
  48.  
  49. public static <L, R> BiOptional<L, R> ofNullables(L left, R right){
  50. if(left != null && right != null){
  51. return new BiOptional<>(left, right, true);
  52. } else{
  53. return BiOptional.empty();
  54. }
  55. }
  56.  
  57. public <T> BiOptional<T, R> mapLeft(Function<? super L, ? extends T> mapper){
  58. Objects.requireNonNull(mapper);
  59. if(present){
  60. return BiOptional.ofNullables(mapper.apply(left), right);
  61. } else{
  62. return BiOptional.empty();
  63. }
  64. }
  65.  
  66. public <T> BiOptional<L, T> mapRight(Function<? super R, ? extends T> mapper){
  67. Objects.requireNonNull(mapper);
  68. if(present){
  69. return BiOptional.ofNullables(left, mapper.apply(right));
  70. } else{
  71. return BiOptional.empty();
  72. }
  73. }
  74.  
  75. public <T, U> BiOptional<T, U> flatMap(BiFunction<? super L, ? super R, ? extends BiOptional<T, U>> mapper){
  76. Objects.requireNonNull(mapper);
  77. if(present){
  78. return Objects.requireNonNull(mapper.apply(left, right));
  79. } else{
  80. return BiOptional.empty();
  81. }
  82. }
  83.  
  84. public <T> Optional<T> merge(BiFunction<? super L, ? super R, ? extends T> merger){
  85. Objects.requireNonNull(merger);
  86. if(present){
  87. return Optional.ofNullable(merger.apply(left, right));
  88. } else{
  89. return Optional.empty();
  90. }
  91. }
  92.  
  93. public OptionalInt mergeToInt(ToIntBiFunction<? super L, ? super R> merger){
  94. Objects.requireNonNull(merger);
  95. if(present){
  96. return OptionalInt.of(merger.applyAsInt(left, right));
  97. } else{
  98. return OptionalInt.empty();
  99. }
  100. }
  101.  
  102. public OptionalLong mergeToLong(ToLongBiFunction<? super L, ? super R> merger){
  103. Objects.requireNonNull(merger);
  104. if(present){
  105. return OptionalLong.of(merger.applyAsLong(left, right));
  106. } else{
  107. return OptionalLong.empty();
  108. }
  109. }
  110.  
  111. public OptionalDouble mergeToDouble(ToDoubleBiFunction<? super L, ? super R> merger){
  112. Objects.requireNonNull(merger);
  113. if(present){
  114. return OptionalDouble.of(merger.applyAsDouble(left, right));
  115. } else{
  116. return OptionalDouble.empty();
  117. }
  118. }
  119.  
  120. public <T> Optional<T> flatMerge(BiFunction<? super L, ? super R, ? extends Optional<T>> merger){
  121. Objects.requireNonNull(merger);
  122. if(present){
  123. return Objects.requireNonNull(merger.apply(left, right));
  124. } else{
  125. return Optional.empty();
  126. }
  127. }
  128.  
  129. public BiOptional<L, R> filter(BiPredicate<? super L, ? super R> predicate){
  130. Objects.requireNonNull(predicate);
  131. if(present && predicate.test(left, right)){
  132. return this;
  133. } else{
  134. return BiOptional.empty();
  135. }
  136. }
  137.  
  138. public boolean isPresent(){
  139. return present;
  140. }
  141.  
  142. @Override
  143. public int hashCode(){
  144. if(present){
  145. return Objects.hash(left, right);
  146. } else{
  147. return 0;
  148. }
  149. }
  150.  
  151. @Override
  152. public boolean equals(Object obj){
  153. if(obj == this){
  154. return true;
  155. }
  156. if(obj == null){
  157. return false;
  158. }
  159. if(!(obj instanceof BiOptional)){
  160. return false;
  161. }
  162.  
  163. final BiOptional<?, ?> other = (BiOptional<?, ?>) obj;
  164. return other.present && present && other.left.equals(left) && other.right.equals(right);
  165. }
  166.  
  167. @Override
  168. public String toString(){
  169. if(present){
  170. return String.format("BiOptional[%s, %s]", left, right);
  171. } else{
  172. return "BiOptional.empty";
  173. }
  174. }
  175. }
Success #stdin #stdout 0.22s 33592KB
stdin
Standard input is empty
stdout
26