marp: true title: Una mirada funciona a Java 22 theme: gaia footer: #commitconf 2024 author: Antonio Muñoz color: #fff transition: fade-out
Antonio Muñoz
var value = switch (input) { case "a" -> 1; case "b" -> 2; default -> 0; };
switch
.public record Movie(String title, int year, int duration) { }
public record Movie(String title, int year, int duration) { public Movie { if (title == null || title.isEmpty()) { throw new IllegalArgumentException(); } } }
public sealed interface Shape { record Square(int side) implements Shape {} record Rectangle(int weight, int height) implements Shape {} record Circle(int radius) implements Shape {} }
non-sealed
public sealed interface Shape { record Square(int side) implements Shape {} record Rectangle(int weight, int height) implements Shape {} record Circle(int radius) implements Shape {} non-sealed interface CustomShape extends Shape {} }
var result = switch (obj) { case Integer i -> String.format("int %d", i); case Long l -> String.format("long %d", l); case Double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> obj.toString(); };
var area = switch (this) { case Square(var side) -> side * side; case Rectangle(var weight, var height) -> weight * height; case Circle(var radious) -> Math.PI * Math.pow(radious, 2); };
var result = switch (point) { case Point(var x, var y) when y == 0 -> processX(x); case Point(var x, var y) -> processXY(x, y); };
when
var result = switch (obj) { case Integer _ -> "int"; case Long _ -> "long"; case Double _ -> "double"; case String _ -> "string"; default -> "other"; };
a + b
a * b
a + 0 <=> a
a * 1 <=> a
(a * b) + (a * c) <=> a * (b + c)
a * b <=> b * a
a + b <=> b + a
a + b + c <=> a + (b + c)
a * b * c <=> a * (b * c)
record
es un producto de tipos.sealed interface
es una suma de tipos.sealed interface List<T> { record NonEmpty<T>(T head, List<T> tail) implements List<T> {} record Empty<T>() implements List<T> {} }
sealed interface List<T> { default <R> List<R> map(Function<T, R> mapper) { return switch (this) { case NonEmpty<T>(var head, var tail) -> new NonEmpty<>(mapper.apply(head), tail.map(mapper)); case Empty<T>() -> new Empty<>(); }; } }
sealed interface List<T> { default List<T> filter(Predicate<T> filter) { return switch (this) { case NonEmpty<T>(var head, var tail) when filter.test(head) -> new NonEmpty<>(head, tail.filter(filter)); case NonEmpty<T>(var head, var tail) -> tail.filter(filter); case Empty<T>() -> new Empty<>(); }; } }
sealed interface List<T> { default T fold(T initial, BinaryOperator<T> operator) { return switch (this) { case NonEmpty<T>(var head, var tail) -> tail.fold(operator.apply(initial, head), operator); case Empty<T>() -> initial; }; } }
sealed interface Tree<T> { record Node<T>(T value, Tree<T> left, Tree<T> right) implements Tree<T> { } record Leaf<T>(T value) implements Tree<T> {} }
sealed interface Optional<T> { record Empty<T>() implements Optional<T> { } record Present<T>(T value) implements Optional<T> {} }
sealed interface Optional<T> { default <R> Optional<R> map(Function<T, R> mapper) { return switch (this) { case Present<T>(var value) -> new Present<>(mapper.apply(value)); case Empty<T> _ -> new Empty<>(); }; } }
sealed interface Optional<T> { default Optional<T> filter(Predicate<T> filter) { return switch (this) { case Present<T>(var value) when filter.test(value) -> this; case Present<T> _ -> new Empty<>(); case Empty<T> _ -> new Empty<>(); }; } }
sealed interface Optional<T> { default <R> R fold(Supplier<R> onEmpty, Function<T, R> onPresent) { return switch (this) { case Present<T>(var value) -> onPresent.apply(value); case Empty<T> _ -> onEmpty.get(); }; } }
sealed interface Either<L, R> { record Left<L, R>(L left) implements Either<L, R> { } record Right<L, R>(R right) implements Either<L, R> {} }
sealed interface Json { enum JsonNull implements Json { NULL } enum JsonBoolean implements Json { TRUE, FALSE } record JsonString(String value) implements Json {} record JsonNumber(Number value) implements Json {} record JsonObject(Map<String, Json> value) implements Json {} record JsonArray(List<Json> value) implements Json {} }
interface MovieRepository { MovieResponse create(Movie movie); } sealed interface MovieResponse permits MovieCreated, MovieError {} record MovieCreated(UUID id) implements MovieResponse {}
sealed interface MovieError extends MovieResponse { record DuplicatedMovie(UUID id) implements MovieError {} record InvalidDuration(int duration) implements MovieError {} record InvalidYear(int year) implements MovieError {} record InvalidStars(int stats) implements MovieError {} record EmptyTitle() implements MovieError {} record EmptyDirector() implements MovieError {} record EmptyCast() implements MovieError {} record DuplicatedActor(String actor) implements MovieError {} }
interface MovieRepository { Either<MovieCreated, MovieError> create(Movie movie); }
var result = switch (obj) { case int i -> String.format("int %d", i); case long l -> String.format("long %d", l); case double d -> String.format("double %f", d); case String s -> String.format("String %s", s); default -> obj.toString(); };
jshell> int i = 0; i ==> 0 jshell> i instanceof byte b $2 ==> true
jshell> int i = 123213; i ==> 123213 jshell> i instanceof byte b $4 ==> false
Point newPoint = oldPoint with { x *= 2; y *= 2; };
var result = switch (optional) { case Optional.of(var value) -> value.toString(); case Optional.empty() -> "empty"; };
var result = switch (optional) { case Point(0, var y) -> process(y); case Point(var x, var y) -> process(x, y); };