Con Java 10, el 20 de marzo de 2018 comenzó el ciclo de lanzamiento de seis meses del JDK. En lugar de esperar años por una actualización importante, ahora recibimos nuevas funciones, y vistas previas de nuevas funciones, cada seis meses.

En este artículo, le mostraremos las novedades de Java 10, aquellas que son de interés para los desarrollares.

Este artículo es parte de una serie que puedes seguir en nuestro canal de Youtube.

En este video te lo explicamos todo.

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class MainJava10 {

    //Local-Variable Type Inference ("var")
    public static void varTypeReference() {
        var i = 10;
        var hello = "Hello world!";
        var list = List.of(1, 2, 3, 4, 5);

        System.out.println("Integer: " + i);
        System.out.println("String: " + hello + " -  is type of " + hello.getClass().getName());
        System.out.println("List: " + list + " -  is type of " + list.getClass().getName());

    }

    // Unmodifiable Collections (List)
    public static void unmodifiableList() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<Integer> unmodifiable = Collections.unmodifiableList(list);

        System.out.println("Type: "+ list.getClass().getName());
        System.out.println("Type: "+ unmodifiable.getClass().getName());
        System.out.println("Values: " + unmodifiable);
    }

    // Unmodifiable Collections (Set)
    public static void unmodifiableSet() {
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        Set<Integer> unmodifiable = Collections.unmodifiableSet(set);

        System.out.println("Type: "+ set.getClass().getName());
        System.out.println("Type: "+ unmodifiable.getClass().getName());
        System.out.println("Values: " + unmodifiable);

    }

    // Unmodifiable Collections (Map)
    public static void unmodifiableMap() {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "hello 1");
        map.put(2, "hello 2");
        map.put(3, "hello 3");

        Map<Integer, String> unmodifiable = Collections.unmodifiableMap(map);

        System.out.println("Type: "+ map.getClass().getName());
        System.out.println("Type: "+ unmodifiable.getClass().getName());
        System.out.println("Values: " + unmodifiable);

    }

    // Unmodifiable Collections NO SON SIEMPRE INMUTABLES.
    // Lee mas aca: https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/util/Collection.html
    public static void unmodifiableMutableInmutableList() {
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);

        List<Integer> list2 = Collections.unmodifiableList(list1);
        List<Integer> list3 = Collections.unmodifiableList(new ArrayList<>(list1));

        list1.add(2);
        list1.add(3);

        System.out.println("List 1 type and values: "+ list1.getClass().getName() + " - " + list1);
        System.out.println("List 2 type and values: "+ list2.getClass().getName() + " - " + list2);
        System.out.println("List 3 type and values: "+ list3.getClass().getName() + " - " + list3);

    }

    // Inmutable copyOf List Collections (apply for: List.copyOf(), Set.copyOf(), and Map.copyOf())
    // Inmutable si es inmutable, no aplica lo mismo del caso anterior.
    public static void inmutableCopyOfList() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<Integer> inmutableCopy = List.copyOf(list);

        System.out.println("Type: "+ list.getClass().getName());
        System.out.println("Type: "+ inmutableCopy.getClass().getName());
    }


    // Collectors.toUnmodifiableList(), toUnmodifiableSet(), and toUnmodifiableMap()
    // Esto es util para la recoleccion en streams
    public static void collectorsToUnmodifiableList() {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        List<Integer> unmodifiable = list.stream().collect(Collectors.toUnmodifiableList());

        System.out.println("Type: "+ list.getClass().getName());
        System.out.println("Type: "+ unmodifiable.getClass().getName());
        System.out.println("Values: " + unmodifiable);

        List<Integer> unmodifiable2 = IntStream.rangeClosed(1,3).boxed().collect(Collectors.toUnmodifiableList());
        System.out.println("Type: "+ unmodifiable2.getClass().getName());
        System.out.println("Values: " + unmodifiable2);

    }

    // Optional.orElseThrow()
    //Tip: Optional.get() es lo mismo que este nuevo metodo :-)
    public static void optionalOrElseThrow() {
        Optional<String> optStr = Optional.of("Pepe");

        System.out.println(optStr.get());
        System.out.println(optStr.orElseThrow());
    }


    public static void main(String[] args) {

        System.out.println("Local-Variable Type Inference");
        varTypeReference();
        System.out.println("\n\n");

        System.out.println("Unmodifiable Collections");
        unmodifiableList();
        unmodifiableSet();
        unmodifiableMap();
        System.out.println("\n\n");

        System.out.println("Unmodifiable Collections are not always inmutables");
        unmodifiableMutableInmutableList();
        System.out.println("\n\n");

        System.out.println("Inmutable Copy Of");
        inmutableCopyOfList();
        System.out.println("\n\n");

        System.out.println("Collectors.toUnmodifiableList()");
        collectorsToUnmodifiableList();
        System.out.println("\n\n");

        System.out.println("Optional.orElseThrow()");
        optionalOrElseThrow();
        System.out.println("\n\n");
        
    }
}

Espero te ayude a aprender.