Skip to content

Instantly share code, notes, and snippets.

@RyanMagnusson
Created March 22, 2023 16:26
Show Gist options
  • Save RyanMagnusson/c8719474936f7968be928efe7bc5315c to your computer and use it in GitHub Desktop.
Save RyanMagnusson/c8719474936f7968be928efe7bc5315c to your computer and use it in GitHub Desktop.
package com.examples.tostring;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.function.Supplier;
import java.util.stream.Stream;
import static java.util.Objects.isNull;
import static org.assertj.core.api.Assertions.assertThat;
public enum Operator {
PLUS("+"), MINUS("-"), MULTIPLY("*");
@Getter @Setter(AccessLevel.NONE)
private String symbol;
Operator(String symbol) { this.symbol = symbol; }
}
interface Value extends Supplier<Integer> {
static final Logger LOGGER = LoggerFactory.getLogger(Value.class);
static Stream<Value> values() {
return Stream.of(new One(), new Two(), new Three(), new Four(), new Five(), new Six(), new Seven(), new Eight(), new Nine(), new Ten());
}
default Value computeWith(Operator op, Value other) {
final Value value = isNull(other) ? new Zero() : other;
Value result = null;
switch(op) {
case PLUS:
result = values().filter(val -> val.get() == (get() + value.get())).findFirst().orElse(null);
if (result == null) {
throw new IndexOutOfBoundsException(String.format("Computing value %d + %d exceeds the limit of 10", get(), value.get()));
}
System.out.println(String.format("[INFO] Computed value %d + %d to equal %d", get(), value.get(), result.get()));
return result;
case MINUS:
result = values().filter(val -> val.get() == (get() - value.get())).findFirst().orElse(null);
if (result == null) {
throw new IndexOutOfBoundsException(String.format("Computing value %d - %d exceeds the lower boundary of 0", get(), value.get()));
}
System.out.println(String.format("[INFO] Computed value %d - %d to equal %d", get(), value.get(), result.get()));
return result;
case MULTIPLY:
if (value.get() == 0) {
return new Zero();
}
final int computed = get() * value.get();
result = values().filter(val -> val.get() == get() * value.get()).findFirst().orElse(null);
if (result == null) {
throw new IndexOutOfBoundsException(String.format("Computing value %d * %d, which is: %d, exceeds the boundary of 0 to 10", get(), value.get(), computed));
}
System.out.println(String.format("[INFO] Computed value %d * %d to equal %d", get(), value.get(), result.get()));
return result;
default:
final String message = String.format("Unknown operation: %d %s %d", get(), op.getSymbol(), value.get());
System.out.println("[INFO] " + message);
throw new UnsupportedOperationException(message);
}
}
}
@ToString
class Zero implements Value {
@Override @JsonGetter("value")
public Integer get() { return 0; }
}
@ToString
class One implements Value {
@Override @JsonGetter("value")
public Integer get() { return 1; }
}
@ToString
class Two implements Value {
@Override @JsonGetter("value")
public Integer get() { return 2; }
}
@ToString
class Three implements Value {
@Override @JsonGetter("value")
public Integer get() { return 3; }
}
@ToString
class Four implements Value {
@Override @JsonGetter("value")
public Integer get() { return 4; }
}
@ToString
class Five implements Value {
@Override @JsonGetter("value")
public Integer get() { return 5; }
}
@ToString
class Six implements Value {
@Override @JsonGetter("value")
public Integer get() { return 6; }
}
@ToString
class Seven implements Value {
@Override @JsonGetter("value")
public Integer get() { return 7; }
}
@ToString
class Eight implements Value {
@Override @JsonGetter("value")
public Integer get() { return 8; }
}
@ToString
class Nine implements Value {
@Override @JsonGetter("value")
public Integer get() { return 9; }
}
@ToString
class Ten implements Value {
@Override @JsonGetter("value")
public Integer get() { return 10; }
}
class Abacus {
final static Logger LOGGER = LoggerFactory.getLogger(Abacus.class);
public static void main(String[] args) {
final Value start = new Zero();
Value computedValue = start.computeWith(Operator.PLUS, new Two());
assertThat(computedValue).isNotNull();
assertThat(computedValue.get()).isEqualTo(2);
computedValue = computedValue.computeWith(Operator.PLUS, new Five());
assertThat(computedValue.get()).isEqualTo(7);
computedValue = computedValue.computeWith(Operator.MINUS, new Four());
assertThat(computedValue.get()).isEqualTo(3);
computedValue = computedValue.computeWith(Operator.MULTIPLY, new Three());
assertThat(computedValue.get()).isEqualTo(9);
Value.values().forEach(val -> System.out.println(String.format("[WARN] @Lombok #toString[%d]: %s", val.get(), val.toString())));
final ObjectMapper mapper = new ObjectMapper();
Value.values().forEach(val -> {
try {
System.out.println(String.format("w/Jackson #toString[%d]: %s", val.get(), mapper.writeValueAsString(val)));
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment