Enum, Record, Exceptions - rlip/java GitHub Wiki

Enum

Typ wyliczeniowy, nie można tworzyć jego instancji. Można dopisywać mu własne funkcje. Ma też metodę toString i values() w standardzie. Można też po prostu wypisać stałe

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
enum Periodicity {
    MONTHLY(0),
    DAILY(86_400),
    WEEKLY(86_400 * 7);

    private static final Map<Integer, Periodicity> periodicityMap = Arrays.stream(Periodicity.values())
            .collect(Collectors.toMap(Periodicity::getNumberOfMinutes, periodicity -> periodicity));
    private final Integer numberOfMinutes;

    @JsonCreator
    static Periodicity forValue(Integer value) {
        return Optional.ofNullable(periodicityMap.get(value))
                .orElseThrow(() -> new ParametrizedException("5735c23e-d668", "Invalid periodicity = " + value, HttpStatus.BAD_REQUEST.value()));
    }

    @JsonValue
    public Integer toValue() {
        for (Map.Entry<Integer, Periodicity> entry : periodicityMap.entrySet()) {
            if (entry.getValue() == this) {
                return entry.getKey();
            }
        }
        String errorMessage = "Cannot convert periodicity = " + this.name() + " to value";
        throw new ParametrizedException("c1159291-f68e", errorMessage, HttpStatus.BAD_REQUEST.value());
    }
}
public enum EmailReportStatus {

    WAITING(1),
    PROCESSING(2),
    COMPLETED(3),
    ERROR(-1);

    private final int codeNr; // Kody tez mogą być stringiem

    EmailReportStatus(int codeNr) {
        this.codeNr = codeNr;
    }

    public int getCodeNr() {
        return codeNr;
    }
}
---------------------------
// Implementacja metody fromString dla typu wyliczeniowego
private static final Map<String, Operation> stringToEnum =
        Stream.of(values()).collect(
           toMap(Object::toString, e -> e)); 
// zwraca Operation dla napisu lub null, jeżeli napis jest nieprawidłowy
public static Optional<Operation> fromString(String symbol) {
   return Optional.ofNullable(stringToEnum.get(symbol));
}
    public static void main(String[] args) {
        var summer = Season.WINTER;
        System.out.println(Season.SUMMER == Season.SUMMER);
        System.out.printf("ENUM name: %s%n", summer.name());
        System.out.println("ORDINAL name: %s".formatted(summer.ordinal()));
        System.out.println("INSTANCE: " + Season.valueOf("FALL"));

        for (Season season: Season.values()) {
            System.out.println(season.ordinal() + ":" + season.name());
        }

        switch (summer) {
            case WINTER -> System.out.println("It's cold");
            case SUMMER -> System.out.println("It's hot");
            default -> System.out.println("It's ok");
        }

        String result = switch (summer) {
            case WINTER -> "It's cold";
            case SUMMER -> "It's hot";
            default -> "It's ok";
        };
        System.out.println(result);


        //---------------------------------

        var earth = Planet.EARTH;
        System.out.printf("Earth mass: %s%n", earth.getMass());
        System.out.printf("G constant: %s%n", Planet.G);
        System.out.printf("Earth gravity: %s%n", earth.gravity());

        //---------------------------------

        var planets = EnumSet.of(Planet.SATURN, Planet.EARTH, Planet.MARS);
        var bigPlanetsCount = planets.stream()
                .filter(plant -> plant.getRadius() > 3)
                .count();
        var planetsDescriptions = new EnumMap<Planet, String>(Planet.class);
        planetsDescriptions.put(Planet.MARS, "Very hot planet");
        planetsDescriptions.put(Planet.EARTH, "Home");
        planetsDescriptions.put(Planet.SATURN, "Cool planet");
    }
//--
public enum Planet {

    EARTH(5.9, 6.3),
    MARS(3.2, 11.1) { //tak można coś nadpisać
        @Override
        public double gravity() {
            return super.gravity() * 0.99;
        }
    },
    SATURN(1.0, 2.5);

    private final double mass;
    private final double radius;

    public static final double G = 6.6e-11;

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double gravity() {
        return G * mass / (radius * radius);
    }

    public double getMass() {
        return mass;
    }

    public double getRadius() {
        return radius;
    }
}

Record

ma getery, toString, a konstruktor i podstawianie danych jest od razu po wypisaniu danych

public record Payment(BigDecimal value, Currency currency, Instant timestamp) {

    public static final Currency DEFAULT_CURRENCY = Currency.PLN;

    public Payment {
        if (value.compareTo(BigDecimal.ZERO) <= 0) {
            throw new IllegalArgumentException();
        }
    }

    Payment(BigDecimal value) {
        this(value, DEFAULT_CURRENCY, Instant.now());
    }

    public boolean isGreaterThan(Payment payment) {
        return this.value.compareTo(payment.value()) > 0;
    }
}

Exceptions

Handler:

@ControllerAdvice
@Slf4j
class RestControllerExceptionHandler {

    @ExceptionHandler(value = AbstractException.class)
    public ResponseEntity<RequestErrorBodyDto> handleException(AbstractException exception) {
        log.debug("Error occurred {}", exception.getMessage());
        return new ResponseEntity<>(RequestErrorBodyDto.from(exception), HttpStatus.valueOf(exception.getHttpStatusCode()));

        
⚠️ **GitHub.com Fallback** ⚠️