Skip to content
Snippets Groups Projects
Commit 09523990 authored by Guyslain's avatar Guyslain
Browse files

TD 8 streams

parent c7301d1b
No related branches found
No related tags found
No related merge requests found
package fr.univamu.progav.td8;
import fr.univamu.progav.td1.ExercicesBoucles;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ExercicesStream {
public interface Person {
int age();
String name();
boolean isFemale();
Person mother();
Person father();
List<Person> children();
}
// Exercice : compléter toutes les méthodes suivantes
// retourne vrai si la stream contient une femme
public static boolean hasFemale(Stream<Person> persons) {
// TODO
return false;
}
// retourne vrai si la stream contient un individu homme et mineur (moins de 18 ans)
public static boolean containsMinorMale(Stream<Person> persons) {
// TODO
return false;
}
// retourne un individu de la stream, femme et ayant au moins un enfant,
// null si aucun individu ne convient
public static Optional<Person> findMother(Stream<Person> persons) {
// TODO
return Optional.empty();
}
// retourne vrai si tous les individus de la stream sont majeurs (âge >= 18)
public static boolean areAllMajor(Stream<Person> persons) {
// TODO
return false;
}
// retourne la liste de tous les hommes de la stream.
public static List<Person> males(Stream<Person> persons) {
// TODO
return List.of();
}
// retourne le nombre de femmes de la stream
public static long nbFemales(Stream<Person> persons) {
// TODO
return 0L;
}
// trouve un individu de la stream ayant un enfant, et retourne l'âge
// de cet enfant.
public static Optional<Integer> ageOfSomeChild(Stream<Person> persons) {
// TODO
return Optional.empty();
}
// retourne la personne la plus agée de la stream,
public static Optional<Person> eldest(Stream<Person> persons) {
// TODO
return Optional.empty();
}
// retourne une chaîne de caractères, comprenant les noms de toutes les
// personnes de la stream, dans l'ordre, séparés par une espace.
public static String names(Stream<Person> persons) {
// TODO
return "";
}
// retourne l'âge moyen des individus de la stream
public static OptionalDouble averageAge(Stream<Person> persons) {
// TODO
return OptionalDouble.empty();
}
private static class SexCount {
// TODO ajouter des propriétés pour compter le nombre d'hommes et de femmes
SexCount() {}
void add(Person p) {
// TODO dénombrer p dans les statistiques
}
void merge(SexCount count) {
// TODO fusionner les statistiques
}
boolean areEquals() {
// TODO renvoyer vrai si les nombres de femmes et d'hommes sont égaux
return false;
}
}
// retourne vrai si les nombres d'hommes et de femmes sont égaux.
public static boolean hasAsManyMalesAsFemales(Stream<Person> persons) {
Supplier<SexCount> supplier = null; // TODO initialiser les 3 variables.
BiConsumer<SexCount, Person> accumulator = null;
BiConsumer<SexCount,SexCount> combiner = null;
return persons
.collect(supplier,accumulator,combiner)
.areEquals();
}
}
Exercice
========
Compléter les méthodes de la classe `ExercicesStream`.
Vous devez utiliser des Stream. Il est interdit d'utiliser des boucles ou
des récursions. Il est interdit de convertir les streams en listes (sauf
pour calculer la liste à retourner dans la méthode ```males```). Toutes
les méthodes doivent avoir une seule instruction, l'instruction ```return```.
La dernière méthode est la plus difficile, elle demande de construire un
collecteur à partir de trois éléments :
- un ```Supplier<R>```, ```R``` étant le type des objets effectuant la
collection, disons un collecteur. Ce ```Supplier``` permet de créer un
nouveau collecteur;
- un ```BiConsumer<R,People>```, qui est une fonction prenant un collecteur
et une personne collectée. C'est en général la méthode du collecteur
chargé d'accepter les personnes collectées l'une après l'autre. Le
collecteur met à jour son état interne pour tenir compte de la personne
collectée.
- un ```BiConsumer<R,R>```, qui est une fonction permettant de fusionner le
travail de deux collecteurs. Le premier collecteur agrège les données
récoltées par le deuxième collecteur dans son état interne.
Pour nous, le collecteur est un objet calculant le nombre de personnes de
chaque sexe. Le premier argument sera donc son constructeur, le deuxième
sera sa méthode ```add```, et le troisième sa méthode ```merge```, chacun
pouvant être donné par une référence de méthode. Une fois le collecteur
effectué, il reste à utiliser la méthode ```areEquals()``` pour déterminer
si le nombre de femmes est égal au nombre d'hommes.
Tous les tests de ```ExercicesStreamTest``` doivent passer à la fin de
l'exercice.
\ No newline at end of file
package fr.univamu.progav.td8;
import fr.univamu.progav.td8.ExercicesStream;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static fr.univamu.progav.td8.ExercicesStream.Person;
import static org.junit.jupiter.api.Assertions.*;
class ExercicesStreamTest {
private record MockPerson(
int age,
String name,
boolean isFemale,
Person mother,
Person father,
List<Person> children
) implements Person {
@Override
public String toString() {
return this.name;
}
}
private static final Person alfa =
new MockPerson(78,"Alfa",true,null,null, new ArrayList<>());
private static final Person bravo =
new MockPerson(82,"Bravo",false,null,null, new ArrayList<>());
private static final Person charlie =
new MockPerson(42,"Charlie",false, alfa,bravo,List.of());
private static final Person delta =
new MockPerson(38,"Delta",false, alfa,bravo, new ArrayList<>());
private static final Person echo =
new MockPerson(41,"Echo",true,null,null, new ArrayList<>());
private static final Person foxtrot =
new MockPerson(7,"Foxtrot",true,echo,delta, List.of());
private static final Person golf =
new MockPerson(25,"Golf",true,null,null, new ArrayList<>());
private static final Person hotel =
new MockPerson(2,"Hotel",false,golf,null, List.of());
private static final Person india =
new MockPerson(8,"India",true,null,null, List.of());
private static final Person juliett =
new MockPerson(18,"Juliett",false,null,null,List.of());
static {
alfa.children().addAll(List.of(charlie, delta));
bravo.children().addAll(List.of(charlie, delta));
delta.children().add(foxtrot);
echo.children().add(foxtrot);
golf.children().add(hotel);
}
private static final List<Person> ALL =
List.of(alfa,bravo,charlie,delta,echo,foxtrot,golf,hotel,india,juliett);
private static Stream<Person> femaleStream() {
return Stream.of(alfa, echo, foxtrot, golf, india);
}
private static Stream<Person> maleStream() {
return Stream.of(bravo,charlie,delta,hotel,juliett);
}
@Test
void hasFemale() {
assertTrue(ExercicesStream.hasFemale(ALL.stream()));
assertFalse(ExercicesStream.hasFemale(Stream.of(bravo,charlie,delta)));
assertTrue(ExercicesStream.hasFemale(Stream.of(alfa)));
assertFalse(ExercicesStream.hasFemale(Stream.of()), "Cas de la stream vide");
}
@Test
void containsMinorMale() {
assertTrue(ExercicesStream.containsMinorMale(ALL.stream()));
assertFalse(ExercicesStream.containsMinorMale(Stream.of(bravo,charlie,delta)), "Pas de mineurs");
assertFalse(ExercicesStream.containsMinorMale(Stream.of(foxtrot,india)), "Pas d'hommes");
assertFalse(ExercicesStream.containsMinorMale(Stream.of()), "Cas de la stream vide");
}
@Test
void findMother() {
Optional<Person> found = ExercicesStream.findMother(ALL.stream());
assertTrue(found.isPresent());
assertTrue(found.get().isFemale() && !found.get().children().isEmpty());
assertEquals(Optional.of(golf),ExercicesStream.findMother(Stream.of(bravo,charlie,delta,golf,hotel,india)));
assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of(bravo,charlie,delta,foxtrot,hotel,india)));
assertEquals(Optional.empty(), ExercicesStream.findMother(Stream.of()), "Cas de la stream vide");
}
@Test
void areAllMajor() {
assertFalse(ExercicesStream.areAllMajor(ALL.stream()));
assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf)));
assertTrue(ExercicesStream.areAllMajor(Stream.of(alfa,bravo,charlie,delta,echo,golf,juliett)), "Cas d'un individu ayant 18 ans");
assertFalse(ExercicesStream.areAllMajor(Stream.of(foxtrot,hotel,india)));
assertTrue(ExercicesStream.areAllMajor(Stream.of()), "Cas de la stream vide");
}
@Test
void ageOfSomeChild() {
Optional<Integer> maybeAge =
ExercicesStream.ageOfSomeChild(Stream.of(hotel, india, juliett, alfa, foxtrot, charlie));
assertTrue(maybeAge.isPresent());
assertTrue(List.of(charlie.age(),delta.age()).contains(maybeAge.get()));
assertTrue(ExercicesStream.ageOfSomeChild(Stream.of(charlie,foxtrot,hotel,india,juliett)).isEmpty());
assertTrue(ExercicesStream.ageOfSomeChild(Stream.of()).isEmpty(),"Cas de la stream vide");
}
@Test
void males() {
List<Person> allMales = ExercicesStream.males(ALL.stream());
List<Person> expected = ALL.stream().filter(p -> !p.isFemale()).toList();
assertNotNull(allMales);
assertEquals(expected.size(), allMales.size(), "Nombre d'hommes incorrect");
for (Person p : expected ) {
assertTrue(allMales.contains(p), p.name() + " est un homme qui n'est pas dans la stream");
}
List<Person> neitherMaleNorFemale = ExercicesStream.males(femaleStream());
assertNotNull(neitherMaleNorFemale);
assertTrue(neitherMaleNorFemale.isEmpty());
List<Person> empty = ExercicesStream.males(Stream.of());
assertNotNull(empty, "Cas de la stream vide");
assertTrue(empty.isEmpty(), "Cas de la stream vide");
}
@Test
void nbFemales() {
assertEquals(0,ExercicesStream.nbFemales(Stream.of()), "Cas de la stream vide");
assertEquals(5,ExercicesStream.nbFemales(ALL.stream()));
assertEquals(0,ExercicesStream.nbFemales(maleStream()));
}
@Test
void eldest() {
assertTrue(ExercicesStream.eldest(Stream.of()).isEmpty(), "Cas de la stream vide");
assertEquals(Optional.of(bravo),ExercicesStream.eldest(ALL.stream()));
}
@Test
void names() {
String allNames = ExercicesStream.names(ALL.stream()).trim();
assertEquals("Alfa Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliett",allNames);
assertEquals("",ExercicesStream.names(Stream.of()), "Cas de la liste vide");
}
@Test
void hasAsManyMalesAsFemales() {
assertTrue(ExercicesStream.hasAsManyMalesAsFemales(Stream.of()), "Cas de la liste vide");
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(alfa)));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(Stream.of(bravo)));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(femaleStream()));
assertFalse(ExercicesStream.hasAsManyMalesAsFemales(maleStream()));
assertTrue(ExercicesStream.hasAsManyMalesAsFemales(ALL.stream()));
}
@Test
void averageAge() {
assertTrue(ExercicesStream.averageAge(Stream.of()).isEmpty(), "Cas de la liste vide");
OptionalDouble average = ExercicesStream.averageAge(ALL.stream());
assertTrue(average.isPresent());
double expected = 34.1;
assertTrue(Math.abs(average.getAsDouble() - expected) < 0.1, "La moyenne correcte est " + expected);
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment