On cherche à écrire une méthode namesOfTheAdults qui prend une liste de personnes en paramètre et renvoie les noms des personnes qui ont 18 ans ou plus.
Si on n'utilise pas l'API des Stream, on va écrire un code qui ressemble à celui-là :
dans le fichier Person.java
public record Person(String name, int age) {}et dans le fichier Streams.java
public class Streams { public static List<String> namesOfTheAdults(List<Person> persons) { var names = new ArrayList<String>(); for(var person: persons) { if (person.age() >= 18) { names.add(person.name()); } } return names; } public static void main(String[] args) { var persons = List.of( new Person("Ana", 21), new Person("John", 17), new Person("Liv", 29)); var names = namesOfTheAdults(persons); System.out.println(names); } }
Quelle est l'interface fonctionnelle prise en paramètre de filter ?
Quels sont les types de paramètre et de retour de la lambda ?
Quelle est l'interface fonctionnelle prise en paramètre de map ?
Quels sont les types de paramètre et de retour de la lambda ?
Écrire une nouvelle version de namesOfTheAdults en utilisant l'API des streams.
On veut maintenant écrire une méthode static sumAge qui prend une liste de Person et qui renvoie un long donnant la somme des ages d'une personne dont le nom commence par la lettre "C".
Si il n'y a aucune personne dont le nom commence par "C", on renverra 0.
Ecrire la méthode long sumAge(List
On cherche à définir un Hotel ayant un nom (name) et une liste de chambres (rooms). La liste des chambres est donnée à la création de l’hôtel et il n'est pas possible d'ajouter des chambres ou de changer le nom de l’hôtel a posteriori.
Une chambre (Room) possède un nom, un numéro d'étage ainsi qu'un prix.
public record Room(String name, int floor, long price) { public Room { Objects.requireNonNull(name, "name is null"); if (floor < 0) { throw new IllegalArgumentException("floor < 0"); } if (price <= 0) { throw new IllegalArgumentException("price <= 0"); } } }
var hotel = new Hotel("paradisio", List.of( new Room("blue", 100, 100), new Room("yellow", 110, 200), new Room("fuchsia", 120, 300), new Room("red", 100, 200), new Room("green", 100, 200) ));
Écrire le type Hotel en faisant attention à ce que la liste des chambres soit non mutable après création.
Écrire une méthode roomInfo qui renvoie une chaîne de caractères contenant les noms des chambres en utilisant un Stream et en assurant que le code suivant fonctionne :
System.out.println(hotel.roomInfo()); // blue, yellow, fuchsia, red, green
Écrire une méthode roomInfoSortedByFloor qui renvoie une chaîne de caractère contenant les noms de chambres triées par le numéro d'étage.
System.out.println(hotel.roomInfoSortedByFloor()); // blue, red, green, yellow, fuchsia
Écrire une méthode averagePrice qui renvoie la moyenne des prix de toutes les chambres. Dans le cas où l’hôtel n'a pas de chambre, on renverra NaN (Not a Number) :
System.out.println(hotel.averagePrice()); // 200.0
Écrire une méthode roomForPrice1 qui prend en paramètre un prix et renvoie la chambre la plus chère en dessous de ce prix. S'il y a plusieurs chambres au même prix, on prendra la première. Cette méthode renvoie un Optional car il peut n'y avoir aucune chambre qui respecte la contrainte de prix.
En termes d'implantation, on choisit de trier pour accéder à la chambre la plus chère. Par ailleurs, il est plus facile de prendre le premier élément (findFirst) d'un Stream que le dernier (il n'y a pas de méthode pour ça) ; on va donc écrire le comparateur de façon à ce que la chambre qui a le prix le plus grand soit en premier.
System.out.println(hotel.roomForPrice1(250)); // Optional[Room[name=yellow, floor=110, price=200]]
En fait, il existe déjà une méthode max sur les Stream. Écrire une méthode roomForPrice2 qui fonctionne comme roomForPrice1 mais en utilisant la méthode max de Stream.
System.out.println(hotel.roomForPrice2(250)); // Optional[Room[name=yellow, floor=110, price=200]]
Écrire une méthode expensiveRoomNames qui prend en paramètre une liste d'hôtels et renvoie les noms des deux (au maximum) chambres les plus chères de chaque hôtel.
var hotel2 = new Hotel("fantastico", List.of( new Room("queen", 1, 200), new Room("king", 1, 500) )); System.out.println(Hotel.expensiveRoomNames(List.of(hotel, hotel2))); // [fuchsia, yellow, king, queen]
On souhaite écrire une méthode roomInfoGroupedByFloor qui renvoie un dictionnaire qui à chaque étage associe une liste des chambres de cet étage :
System.out.println(hotel.roomInfoGroupedByFloor()); // {100=[Room[name=blue, ...], Room[name=red, ...], Room[name=green, ...]], 120=[Room[name=fuchsia, ...]], 110=[Room[name=yellow, ...]]}
La méthode précédente ne renvoie pas un dictionnaire qui trie les clés, donc les étages ne sont pas forcément dans l'ordre. En Java, il existe une classe java.util.TreeMap qui maintient les clés triées. Écrire une méthode roomInfoGroupedByFloorInOrder qui a la même signature que la méthode précédente mais renvoie un dictionnaire qui stocke les clés de façon triée.
System.out.println(hotel.roomInfoGroupedByFloorInOrder()); // {100=[Room[name=blue, ...], Room[name=red, ...], Room[name=green, ...]], 110=[Room[name=yellow, ...]], 120=[Room[name=fuchsia, ...]]}