/* package whatever; // don't place package name! */
import java.util.*;
import java.util.function.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
BiOptional.of("Some thing", "Some other thing")
.
ifPresent(System.
out::println
); }
}
final class BiOptional<L, R>{
private static final BiOptional<?, ?> EMPTY = new BiOptional<>(null, null, false);
private final L left;
private final R right;
private final boolean present;
private BiOptional(L left, R right, boolean present){
this.left = left;
this.right = right;
this.present = present;
}
public static <L, R> BiOptional<L, R> empty(){
@SuppressWarnings("unchecked")
final BiOptional<L, R> empty = (BiOptional<L, R>) EMPTY;
return empty;
}
public static <L, R> BiOptional<L, R> of(L left, R right){
return new BiOptional<>(
Objects.requireNonNull(left),
Objects.requireNonNull(right),
true
);
}
public static <L, R> BiOptional<L, R> ofNullables(L left, R right){
if(left != null && right != null){
return new BiOptional<>(left, right, true);
} else{
return BiOptional.empty();
}
}
public <T> BiOptional<T, R> mapLeft(Function<? super L, ? extends T> mapper){
Objects.requireNonNull(mapper);
if(present){
return BiOptional.ofNullables(mapper.apply(left), right);
} else{
return BiOptional.empty();
}
}
public <T> BiOptional<L, T> mapRight(Function<? super R, ? extends T> mapper){
Objects.requireNonNull(mapper);
if(present){
return BiOptional.ofNullables(left, mapper.apply(right));
} else{
return BiOptional.empty();
}
}
public <T, U> BiOptional<T, U> flatMap(BiFunction<? super L, ? super R, ? extends BiOptional<T, U>> mapper){
Objects.requireNonNull(mapper);
if(present){
return Objects.requireNonNull(mapper.apply(left, right));
} else{
return BiOptional.empty();
}
}
public <T> Optional<T> merge(BiFunction<? super L, ? super R, ? extends T> merger){
Objects.requireNonNull(merger);
if(present){
return Optional.ofNullable(merger.apply(left, right));
} else{
return Optional.empty();
}
}
public OptionalInt mergeToInt(ToIntBiFunction<? super L, ? super R> merger){
Objects.requireNonNull(merger);
if(present){
return OptionalInt.of(merger.applyAsInt(left, right));
} else{
return OptionalInt.empty();
}
}
public OptionalLong mergeToLong(ToLongBiFunction<? super L, ? super R> merger){
Objects.requireNonNull(merger);
if(present){
return OptionalLong.of(merger.applyAsLong(left, right));
} else{
return OptionalLong.empty();
}
}
public OptionalDouble mergeToDouble(ToDoubleBiFunction<? super L, ? super R> merger){
Objects.requireNonNull(merger);
if(present){
return OptionalDouble.of(merger.applyAsDouble(left, right));
} else{
return OptionalDouble.empty();
}
}
public <T> Optional<T> flatMerge(BiFunction<? super L, ? super R, ? extends Optional<T>> merger){
Objects.requireNonNull(merger);
if(present){
return Objects.requireNonNull(merger.apply(left, right));
} else{
return Optional.empty();
}
}
public BiOptional<L, R> filter(BiPredicate<? super L, ? super R> predicate){
Objects.requireNonNull(predicate);
if(present && predicate.test(left, right)){
return this;
} else{
return BiOptional.empty();
}
}
public boolean isPresent(){
return present;
}
@Override
public int hashCode(){
if(present){
return Objects.hash(left, right);
} else{
return 0;
}
}
@Override
public boolean equals
(Object obj
){ if(obj == this){
return true;
}
if(obj == null){
return false;
}
if(!(obj instanceof BiOptional)){
return false;
}
final BiOptional<?, ?> other = (BiOptional<?, ?>) obj;
return other.present && present && other.left.equals(left) && other.right.equals(right);
}
@Override
if(present){
return String.
format("BiOptional[%s, %s]", left, right
); } else{
return "BiOptional.empty";
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKCmltcG9ydCBqYXZhLnV0aWwuKjsKaW1wb3J0IGphdmEudXRpbC5mdW5jdGlvbi4qOwoKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CgkJQmlPcHRpb25hbC5vZigiU29tZSB0aGluZyIsICJTb21lIG90aGVyIHRoaW5nIikKICAgICAgICAgICAgCQkubWFwTGVmdChTdHJpbmc6Omxlbmd0aCkKICAgICAgICAgICAgCQkubWFwUmlnaHQoU3RyaW5nOjpsZW5ndGgpCiAgICAgICAgICAgIAkJLm1lcmdlVG9JbnQoSW50ZWdlcjo6c3VtKQogICAgICAgICAgICAJCS5pZlByZXNlbnQoU3lzdGVtLm91dDo6cHJpbnRsbik7Cgl9Cn0KCmZpbmFsIGNsYXNzIEJpT3B0aW9uYWw8TCwgUj57CgogICAgcHJpdmF0ZSBzdGF0aWMgZmluYWwgQmlPcHRpb25hbDw/LCA/PiBFTVBUWSA9IG5ldyBCaU9wdGlvbmFsPD4obnVsbCwgbnVsbCwgZmFsc2UpOwoKICAgIHByaXZhdGUgZmluYWwgTCBsZWZ0OwogICAgcHJpdmF0ZSBmaW5hbCBSIHJpZ2h0OwogICAgcHJpdmF0ZSBmaW5hbCBib29sZWFuIHByZXNlbnQ7CgogICAgcHJpdmF0ZSBCaU9wdGlvbmFsKEwgbGVmdCwgUiByaWdodCwgYm9vbGVhbiBwcmVzZW50KXsKICAgICAgICB0aGlzLmxlZnQgPSBsZWZ0OwogICAgICAgIHRoaXMucmlnaHQgPSByaWdodDsKICAgICAgICB0aGlzLnByZXNlbnQgPSBwcmVzZW50OwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgPEwsIFI+IEJpT3B0aW9uYWw8TCwgUj4gZW1wdHkoKXsKICAgICAgICBAU3VwcHJlc3NXYXJuaW5ncygidW5jaGVja2VkIikKICAgICAgICBmaW5hbCBCaU9wdGlvbmFsPEwsIFI+IGVtcHR5ID0gKEJpT3B0aW9uYWw8TCwgUj4pIEVNUFRZOwogICAgICAgIHJldHVybiBlbXB0eTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxMLCBSPiBCaU9wdGlvbmFsPEwsIFI+IG9mKEwgbGVmdCwgUiByaWdodCl7CiAgICAgICAgcmV0dXJuIG5ldyBCaU9wdGlvbmFsPD4oCiAgICAgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwobGVmdCksCiAgICAgICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwocmlnaHQpLAogICAgICAgICAgICB0cnVlCiAgICAgICAgKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIDxMLCBSPiBCaU9wdGlvbmFsPEwsIFI+IG9mTnVsbGFibGVzKEwgbGVmdCwgUiByaWdodCl7CiAgICAgICAgaWYobGVmdCAhPSBudWxsICYmIHJpZ2h0ICE9IG51bGwpewogICAgICAgICAgICByZXR1cm4gbmV3IEJpT3B0aW9uYWw8PihsZWZ0LCByaWdodCwgdHJ1ZSk7CiAgICAgICAgfSBlbHNlewogICAgICAgICAgICByZXR1cm4gQmlPcHRpb25hbC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgPFQ+IEJpT3B0aW9uYWw8VCwgUj4gbWFwTGVmdChGdW5jdGlvbjw/IHN1cGVyIEwsID8gZXh0ZW5kcyBUPiBtYXBwZXIpewogICAgICAgIE9iamVjdHMucmVxdWlyZU5vbk51bGwobWFwcGVyKTsKICAgICAgICBpZihwcmVzZW50KXsKICAgICAgICAgICAgcmV0dXJuIEJpT3B0aW9uYWwub2ZOdWxsYWJsZXMobWFwcGVyLmFwcGx5KGxlZnQpLCByaWdodCk7CiAgICAgICAgfSBlbHNlewogICAgICAgICAgICByZXR1cm4gQmlPcHRpb25hbC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgPFQ+IEJpT3B0aW9uYWw8TCwgVD4gbWFwUmlnaHQoRnVuY3Rpb248PyBzdXBlciBSLCA/IGV4dGVuZHMgVD4gbWFwcGVyKXsKICAgICAgICBPYmplY3RzLnJlcXVpcmVOb25OdWxsKG1hcHBlcik7CiAgICAgICAgaWYocHJlc2VudCl7CiAgICAgICAgICAgIHJldHVybiBCaU9wdGlvbmFsLm9mTnVsbGFibGVzKGxlZnQsIG1hcHBlci5hcHBseShyaWdodCkpOwogICAgICAgIH0gZWxzZXsKICAgICAgICAgICAgcmV0dXJuIEJpT3B0aW9uYWwuZW1wdHkoKTsKICAgICAgICB9CiAgICB9CgogICAgcHVibGljIDxULCBVPiBCaU9wdGlvbmFsPFQsIFU+IGZsYXRNYXAoQmlGdW5jdGlvbjw/IHN1cGVyIEwsID8gc3VwZXIgUiwgPyBleHRlbmRzIEJpT3B0aW9uYWw8VCwgVT4+IG1hcHBlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtYXBwZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtYXBwZXIuYXBwbHkobGVmdCwgcmlnaHQpKTsKICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgIHJldHVybiBCaU9wdGlvbmFsLmVtcHR5KCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyA8VD4gT3B0aW9uYWw8VD4gbWVyZ2UoQmlGdW5jdGlvbjw/IHN1cGVyIEwsID8gc3VwZXIgUiwgPyBleHRlbmRzIFQ+IG1lcmdlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT3B0aW9uYWwub2ZOdWxsYWJsZShtZXJnZXIuYXBwbHkobGVmdCwgcmlnaHQpKTsKICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgT3B0aW9uYWxJbnQgbWVyZ2VUb0ludChUb0ludEJpRnVuY3Rpb248PyBzdXBlciBMLCA/IHN1cGVyIFI+IG1lcmdlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT3B0aW9uYWxJbnQub2YobWVyZ2VyLmFwcGx5QXNJbnQobGVmdCwgcmlnaHQpKTsKICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgIHJldHVybiBPcHRpb25hbEludC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgT3B0aW9uYWxMb25nIG1lcmdlVG9Mb25nKFRvTG9uZ0JpRnVuY3Rpb248PyBzdXBlciBMLCA/IHN1cGVyIFI+IG1lcmdlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT3B0aW9uYWxMb25nLm9mKG1lcmdlci5hcHBseUFzTG9uZyhsZWZ0LCByaWdodCkpOwogICAgICAgIH0gZWxzZXsKICAgICAgICAgICAgcmV0dXJuIE9wdGlvbmFsTG9uZy5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgT3B0aW9uYWxEb3VibGUgbWVyZ2VUb0RvdWJsZShUb0RvdWJsZUJpRnVuY3Rpb248PyBzdXBlciBMLCA/IHN1cGVyIFI+IG1lcmdlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT3B0aW9uYWxEb3VibGUub2YobWVyZ2VyLmFwcGx5QXNEb3VibGUobGVmdCwgcmlnaHQpKTsKICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgIHJldHVybiBPcHRpb25hbERvdWJsZS5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgPFQ+IE9wdGlvbmFsPFQ+IGZsYXRNZXJnZShCaUZ1bmN0aW9uPD8gc3VwZXIgTCwgPyBzdXBlciBSLCA/IGV4dGVuZHMgT3B0aW9uYWw8VD4+IG1lcmdlcil7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIpOwogICAgICAgIGlmKHByZXNlbnQpewogICAgICAgICAgICByZXR1cm4gT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChtZXJnZXIuYXBwbHkobGVmdCwgcmlnaHQpKTsKICAgICAgICB9IGVsc2V7CiAgICAgICAgICAgIHJldHVybiBPcHRpb25hbC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgQmlPcHRpb25hbDxMLCBSPiBmaWx0ZXIoQmlQcmVkaWNhdGU8PyBzdXBlciBMLCA/IHN1cGVyIFI+IHByZWRpY2F0ZSl7CiAgICAgICAgT2JqZWN0cy5yZXF1aXJlTm9uTnVsbChwcmVkaWNhdGUpOwogICAgICAgIGlmKHByZXNlbnQgJiYgcHJlZGljYXRlLnRlc3QobGVmdCwgcmlnaHQpKXsKICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgfSBlbHNlewogICAgICAgICAgICByZXR1cm4gQmlPcHRpb25hbC5lbXB0eSgpOwogICAgICAgIH0KICAgIH0KCiAgICBwdWJsaWMgYm9vbGVhbiBpc1ByZXNlbnQoKXsKICAgICAgICByZXR1cm4gcHJlc2VudDsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKXsKICAgICAgICBpZihwcmVzZW50KXsKICAgICAgICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaChsZWZ0LCByaWdodCk7CiAgICAgICAgfSBlbHNlewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG9iail7CiAgICAgICAgaWYob2JqID09IHRoaXMpewogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYob2JqID09IG51bGwpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQogICAgICAgIGlmKCEob2JqIGluc3RhbmNlb2YgQmlPcHRpb25hbCkpewogICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfQoKICAgICAgICBmaW5hbCBCaU9wdGlvbmFsPD8sID8+IG90aGVyID0gKEJpT3B0aW9uYWw8PywgPz4pIG9iajsKICAgICAgICByZXR1cm4gb3RoZXIucHJlc2VudCAmJiBwcmVzZW50ICYmIG90aGVyLmxlZnQuZXF1YWxzKGxlZnQpICYmIG90aGVyLnJpZ2h0LmVxdWFscyhyaWdodCk7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgU3RyaW5nIHRvU3RyaW5nKCl7CiAgICAgICAgaWYocHJlc2VudCl7CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCJCaU9wdGlvbmFsWyVzLCAlc10iLCBsZWZ0LCByaWdodCk7CiAgICAgICAgfSBlbHNlewogICAgICAgICAgICByZXR1cm4gIkJpT3B0aW9uYWwuZW1wdHkiOwogICAgICAgIH0KICAgIH0KfQ==