import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
import java.util.function.*;
// The main method must be in a class named "Main".
class Main {
public static void main(String[] args) {
UserValidationExample.run();
OrderProcessingExample.run();
}
}
class UserValidationExample {
public static void run() {
User user = new User("", "invalid-email", -5);
Result<User> validationResult = validateUser(user);
validationResult
.onSuccess(u -> System.out.println("User is valid: " + u))
.onFailure(error -> System.err.println("Validation failed: " + error));
}
public static Result<User> validateUser(User user) {
return validateName(user)
.flatMap(UserValidationExample::validateEmail)
.flatMap(UserValidationExample::validateAge);
}
private static Result<User> validateName(User user) {
return Result.ensure(
user,
u -> u.name() != null && !u.name().isBlank(),
"Name cannot be empty"
);
}
private static Result<User> validateEmail(User user) {
return Result.ensure(
user,
u -> u.email() != null && u.email().contains("@"),
"Email must be valid"
);
}
private static Result<User> validateAge(User user) {
return Result.ensure(
user,
u -> u.age() >= 0,
"Age cannot be negative"
);
}
}
record User(String name, String email, int age) {}
class OrderProcessingExample {
public static void run() {
Order order = new Order(
List.of(
new OrderItem("Book", new BigDecimal("29.99"), 2),
new OrderItem("Pen", new BigDecimal("5.99"), 5)
),
"john@example.com"
);
Result<Receipt> receiptResult = processOrder(order);
receiptResult
.onSuccess(receipt -> System.out.println("Order processed successfully: " + receipt))
.onFailure(error -> System.err.println("Failed to process order: " + error));
}
public static Result<Receipt> processOrder(Order order) {
return validateOrder(order)
.flatMap(OrderProcessingExample::calculateTotal)
.flatMap(OrderProcessingExample::applyDiscounts)
.flatMap(OrderProcessingExample::processPayment)
.map(OrderProcessingExample::generateReceipt);
}
private static Result<Order> validateOrder(Order order) {
if (order == null) {
return Result.failure("Order cannot be null");
}
if (order.items().isEmpty()) {
return Result.failure("Order must have at least one item");
}
if (order.customerEmail() == null || !order.customerEmail().contains("@")) {
return Result.failure("Valid customer email is required");
}
return Result.success(order);
}
private static Result<Order> calculateTotal(Order order) {
try {
BigDecimal total = order.items().stream()
.map(item -> item.price().multiply(BigDecimal.valueOf(item.quantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
return Result.success(new Order(order.items(), order.customerEmail(), total));
} catch (Exception e) {
return Result.failure("Failed to calculate total: " + e.getMessage());
}
}
private static Result<Order> applyDiscounts(Order order) {
// Aplicar un 10% de descuento si el total es mayor a 100
if (order.total().compareTo(new BigDecimal("100")) > 0) {
BigDecimal discount = order.total().multiply(new BigDecimal("0.1"));
BigDecimal discountedTotal = order.total().subtract(discount);
return Result.success(new Order(
order.items(),
order.customerEmail(),
discountedTotal,
discount
));
}
return Result.success(order);
}
private static Result<Order> processPayment(Order order) {
// Simulación de procesamiento de pago
if (order.total().compareTo(new BigDecimal("1000")) > 0) {
return Result.failure("Amount exceeds maximum allowed for online payment");
}
// Simular éxito del pago
return Result.success(order);
}
private static Receipt generateReceipt(Order order) {
return new Receipt(
UUID.randomUUID().toString(),
order.items(),
order.total(),
order.discount(),
System.currentTimeMillis()
);
}
}
record Order(
List<OrderItem> items,
String customerEmail,
BigDecimal total,
BigDecimal discount
) {
public Order(List<OrderItem> items, String customerEmail) {
this(items, customerEmail, BigDecimal.ZERO, BigDecimal.ZERO);
}
public Order(List<OrderItem> items, String customerEmail, BigDecimal total) {
this(items, customerEmail, total, BigDecimal.ZERO);
}
}
record OrderItem(String name, BigDecimal price, int quantity) {}
record Receipt(
String id,
List<OrderItem> items,
BigDecimal total,
BigDecimal discount,
long timestamp
) {}
interface Result<T> {
static <T> Result<T> success(T value) {
return new Success<>(value);
}
static <T> Result<T> failure(String error) {
return new Failure<>(error);
}
static <T> Result<T> of(Supplier<T> supplier) {
try {
return Result.success(supplier.get());
} catch (Exception e) {
return Result.failure(e.getMessage());
}
}
static <T> Result<T> ensure(T value, Predicate<T> predicate, String errorMessage) {
return predicate.test(value)
? Result.success(value)
: Result.failure(errorMessage);
}
boolean isSuccess();
boolean isFailure();
T getValue();
String getError();
<U> Result<U> map(Function<T, U> mapper);
<U> Result<U> flatMap(Function<T, Result<U>> mapper);
Result<T> onSuccess(Consumer<T> consumer);
Result<T> onFailure(Consumer<String> consumer);
T orElse(T defaultValue);
T orElseThrow();
T orElseThrow(Function<String, ? extends RuntimeException> exceptionMapper);
}
record Success<T>(T value) implements Result<T> {
public Success {
Objects.requireNonNull(value, "Value cannot be null");
}
@Override
public boolean isSuccess() {
return true;
}
@Override
public boolean isFailure() {
return false;
}
@Override
public T getValue() {
return value;
}
@Override
public String getError() {
throw new IllegalStateException("Cannot get error from Success");
}
@Override
public <U> Result<U> map(Function<T, U> mapper) {
try {
return Result.success(mapper.apply(value));
} catch (Exception e) {
return Result.failure("Error during mapping: " + e.getMessage());
}
}
@Override
public <U> Result<U> flatMap(Function<T, Result<U>> mapper) {
try {
return mapper.apply(value);
} catch (Exception e) {
return Result.failure("Error during flatMapping: " + e.getMessage());
}
}
@Override
public Result<T> onSuccess(Consumer<T> consumer) {
consumer.accept(value);
return this;
}
@Override
public Result<T> onFailure(Consumer<String> consumer) {
return this;
}
@Override
public T orElse(T defaultValue) {
return value;
}
@Override
public T orElseThrow() {
return value;
}
@Override
public T orElseThrow(Function<String, ? extends RuntimeException> exceptionMapper) {
return value;
}
}
record Failure<T>(String error) implements Result<T> {
public Failure {
Objects.requireNonNull(error, "Error cannot be null");
}
@Override
public boolean isSuccess() {
return false;
}
@Override
public boolean isFailure() {
return true;
}
@Override
public T getValue() {
throw new IllegalStateException("Cannot get value from Failure");
}
@Override
public String getError() {
return error;
}
@Override
public <U> Result<U> map(Function<T, U> mapper) {
return Result.failure(error);
}
@Override
public <U> Result<U> flatMap(Function<T, Result<U>> mapper) {
return Result.failure(error);
}
@Override
public Result<T> onSuccess(Consumer<T> consumer) {
return this;
}
@Override
public Result<T> onFailure(Consumer<String> consumer) {
consumer.accept(error);
return this;
}
@Override
public T orElse(T defaultValue) {
return defaultValue;
}
@Override
public T orElseThrow() {
throw new RuntimeException(error);
}
@Override
public T orElseThrow(Function<String, ? extends RuntimeException> exceptionMapper) {
throw exceptionMapper.apply(error);
}
}
To embed this project on your website, copy the following code and paste it into your website's HTML: