# Dernière fonctionalités utiles du JDK 17

> Je n&rsquo;ai ici gardé que les plus importants changements à utiliser.


<a id="org5e08597"></a>

## Depuis JDK 8


<a id="org9ddd3fb"></a>

### Lambdas et interfaces fonctionnelles

Les lambdas qui sont des fonctions anonymes stoquées dans des variables. Et les interfaces fonctionnelles sont des interfaces n&rsquo;ayant qu&rsquo;une seule méthode pour une lambda.

Grâce à cela, on peut avoir des types de fonctions plus précis et rendre le code plus sûr.

Voici un exemple d'interface fonctionnelle :

```java
// Définition d'une interface foncitonnelle "MyFunction" ayant une fonction prenant en argument 2 int et en retournant 1
@FunctionalInterface
interface MyFunction {
    int apply(int x, int y);
}

// On peut ensuite créer une lambda suivant cette interface
// Le type est donc MyFunction, les arguments sont x et y et le corps de la méthode est après la flèche
MyFunction add = (x, y) -> x + y;

// On peut ensuite utiliser notre fonction
System.out.println(add.apply(1,1)); // Ceci va afficher "2"
```

<a id="orgf858b7b"></a>

### Default methods in interfaces

Maintenant on peut écrire un code par défault dans les interfaces (rendant donc l&rsquo;implémentation de ces méthodes par défault optionnelle).

```java
public interface Vehicle {
    // Ceci sont des méthodes d'interface normales, il est donc obligatoire de les écrire pour implémenter l'interface
    String getBrand();
    String speedUp();
    String slowDown();

    // Ceci sont des méthodes ayant un code par défault, il n'est donc pas obligatoire de les écrire pour implémenter l'interface
    default String turnAlarmOn() {
        return "Turning the vehicle alarm on.";
    }

    default String turnAlarmOff() {
        return "Turning the vehicle alarm off.";
    }
}
```

<a id="orgac47c69"></a>

### Date and time API

Avant Java 8 il n&rsquo;y avais pas d&rsquo;API par défault pour gérer le temps et les dates. Maintenant il y en a une. Vous pouvez avoir tous les détails dans [la Javadoc de java.time](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/time/package-summary.html).

A partir de Java 8 on peut simplement récupérer la date et l&rsquo;heure actuelle en faisant `LocalDateTime.now()`.


<a id="orga35c0a5"></a>

### Stream API

Pour expliquer plus en détails les avantages de la stream API, voici quelques exemples de code avec et sans stream.

Les streams API sont assez important et sont attendu à l&rsquo;AI.

Vous pouvez apprendre à les utiliser en regardant [la Javadoc de Stream](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/stream/Stream.html).

#### Exemple 1

Sans stream api :

```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int number: numbers) {
    if (number % 2 == 0) {
        System.out.println(number);
    }
}
```

Avec stream api :

```java
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);
```

#### Exemple 2

Sans stream api :

```java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name: names) {
    System.out.println(name.toUpperCase());
}
```

Avec stream api :

```java
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.stream() // Génère le Stream
    .map(String::toUpperCase) // Passe tout en uppercase
    .forEach(System.out::println); // Print chaque élément dans la console
```

#### Exemple 3

Imaginons que l&rsquo;on a une liste de valeurs en nombre et en String et que l&rsquo;on veut faire la moyenne tout en passant le premier élément :

Sans la stream API :

```java
public static double getAverage(List<String> values) {
    double sum = 0.0;                                           // Commence à 0
    final int counter = values.size();                          // Compte le nombre d'items dans la liste
    if (list.isEmpty()) return 0;                               // Retourne 0 si la liste est vide pour empécher une division par 0
    for (int i = 1; i < values.size(); i++) {                   // Fait une boucle passant le premier item
        String stringValue = value.get(i);                      // Récupère la valeur en String
        double numericValue = Double.parseDouble(stringValue);  // La converti en nombre
        sum += numericValue;                                    // L'ajoute à la somme
    }
    return sum / counter;                                       // Fait le calcul de la somme
}
```

Avec la stream API :

```java
public static double getAverage(List<String> values) {
    return values.stream()                               // Converti la liste en Stream
        .skip(1)                                         // Passer le premier élément
        .mapToDouble(value -> Double.parseDouble(value)) // Tout convertir en double
        .average()                                       // Caluler la moyenne de tout
        .orElse(0.0);                                    // Si la liste est vide, va retourner 0
}
```

<a id="org57cb91b"></a>

## Depuis JDK 9


<a id="orgc65f7f4"></a>

### Listes immuables

On peut maintenant créer des listes (ou d&rsquo;autres collections) immuables en Java avec `of` ou `copyOf` :

```java
List<String> list = List.of("Hello", "World");
```

<a id="orgceadb17"></a>

## Depuis JDK 10-11


<a id="orgad54889"></a>

### Inférence de type

Depuis Java 10 ou 11 on peut maintenant utiliser l&rsquo;infférence de type, on est donc plus obligé de préciser le type d&rsquo;une variable locale. On peut simplement utiliser le mot clé `var`

```java
// Avant Java 10
String message = "Hello, World!";

// Possible après Java 10
var message = "Hello, World!";
``` 

<a id="orgc49f7d1"></a>

## JDK 17


<a id="org3ff0356"></a>

### Sealed classes

Les *sealed classes* permettent de limiter les classes qui peuvent hériter de la classe actuelle. Il n&rsquo;est pas recommandé d&rsquo;utiliser ceci pour la même raison qu&rsquo;il n&rsquo;est pas recommandé d&rsquo;utiliser l&rsquo;héritage.

```java
// Seule les classes Cricle et Square pourront hériter de Shape
public sealed class Shape permits Circle, Square {
}
```

<a id="org11ad44b"></a>

### Switch expressions

Les switch peuvent maintenant fonctionner avec n&rsquo;importe quel type (et pas uniquement int comme avant), de plus on peut en écrire plusieurs sur la même ligne :

```java
int month = 2;
int daysInMonth = switch (month) {
    case 1, 3, 5, 7, 8, 10, 12 -> 31;
    case 4, 6, 9, 11 -> 30;
    case 2 -> 28;
    default -> throw new IllegalArgumentException("Invalid month: " + month);
};
```


<a id="orga0d3b43"></a>

### Records

Les records permettent de créer très simplement des data class pour représenter certains concepts et les stoquer.

Voici comment représenter une Personne avec un nom et un age avant les Records :

```java
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return this.name;
    }

    public int getAge() {
        return this.age;
    }
}
```

Et voici comment représenter à peu près la même chose avec un Record

```java
record Person(String name, int age) {}
```

<a id="orgeb6ca7c"></a>

### Text blocks

Depuis JDK 17 on peut aussi simplement faire des Strings de plusieurs lignes avec `"""`.

Voici comment faire un String de 3 lignes avant JDK 17 :

```java
String message = "Welcome\n How are you?\n I hope you have a nice day";
```

Et voici comment faire la même chose depuis JDK 17 :

```java
String message = """
                 Welcome
                 How are you?
                 I hope you have a nice day
                 """;
```