Effectivement il faut itérer sur tous les jours de l'année 2014.
Je vous remercie encore à tous pour votre soutien, et cela m'a permis de découvrir la bibliothèque Joda-Time et les erreurs à éviter avec les Maps.
Effectivement il faut itérer sur tous les jours de l'année 2014.
Je vous remercie encore à tous pour votre soutien, et cela m'a permis de découvrir la bibliothèque Joda-Time et les erreurs à éviter avec les Maps.
Bonjour ,
Comment feriez-vous pour récupérer les 10 jours les plus chauds de l'année 2014?
Merci par avance.
Transact.
plusieurs solutions :
1. trier tes entrées -> récupérer les 10 premieres
Pour cela, la classe Map te permet de récupérer la liste des entrées (couple date/température) que tu peux récupérer à l'aide de entrySet
Ensuite pour tu mets tout cela dans un liste qu'il suffit de trier (Collections.sort) à l'aide d'un comparator adéquate.
2. parcourir l'ensemble de tes entrées et maintenir une liste des 10 plus chaudes
Tu te fais une petite liste destiner à recevoir les 10 meilleurs entrées.
Tu parcours ensuite l'ensemble des entrees de ta Map, pour chaque entrée, tu vérifies qu'elle entre dans le top 10, et si c'est le cas, tu supprimes la moins bonne.
En terme de compléxité, pour le nombre d'entrées que tu va avoir (365), ca ne devrait pas changer grand chose entre les deux solutions. La plus simple à implémenter étant la première.
Merci pour ta réponse benratti, d'ailleurs je pensai utiliser la méthode compare de l'interface Comparator mais je ne voyais pas comment l'implémenter dans le code existant.
Je regarde comment faire et je te tiens au courant.
J'ai crée une classe interne implémentant l'interface Comparator pour bénéficier de la méthode compare(T o1, T o2) par contre j'ai le message suivant :
Code java : Sélectionner tout - Visualiser dans une fenêtre à part No suitable method found for sort(List<LocalDate>,TestTemperature.TemperatureComparator)
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public SortedMap<LocalDate, Float> genererTemperatures10joursPlusChaud() { List<LocalDate> valueList = new ArrayList(tMapTemperatures.values()); // Les valeurs de la liste // Parcours sur les dates, tant qu'on est sur la même année pour récupérer tous les jours de l'année for (LocalDate jour = firstDay; jour.getYear() == YEAR; jour = jour.plusDays(1)) { // S'occuper de récupérer les températures Float temperatures = (rand.nextInt(2 * (MAX - MIN)) + 1 + 2 * MIN) / 2f; // Alimenter la TreeMap tMapTemperatures.put(jour, temperatures); } // Afficher le relevé généré aléatoirement for (Map.Entry<LocalDate, Float> entry : tMapTemperatures.entrySet()) { LocalDate date = entry.getKey(); Float temperature = entry.getValue(); // Trier les clés de la Map en utilisant le Comparator Collections.sort(valueList, new TemperatureComparator()); //System.out.println(date.toString("dd/MM/YYYY") + " : " + temperature + " °C"); } return tMapTemperatures; } public class TemperatureComparator implements Comparator<Float> { @Override public int compare(Float o1, Float o2) { return (o1 < o2 ? -1 : (Objects.equal(o1, o1) ? 0 : 1)); } }
Tu essaie de trier une List<LocalDate> avec un Comparator<Float>, donc forcement ca ne passera pas...
Tu dois créer un Comparator<LocalDate> mais qui fera le test de la comparaison sur les températures aux deux dates données.
Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.
suivez mon blog sur Développez.
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook
De plus une grande partie des objets de base sont déjà Comparable, donc tu n'as pas à créer de Comparator tant que tu restes sur l'ordre "naturel" :
Mais ton problème avec ca, c'est que tu obtiendras une liste de températures trié... sans aucun lien avec les dates associés...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 Collections.sort(valueList); // Trie selon l'ordre naturel des objets Collections.sort(valueList, Collections.reverseOrder()); // Trie selon l'ordre inverse
(et en plus tu refais le tri à chaque itération de la boucle)
Le choix de la collection est discutable.
Une Map c'est bien si tu dois accéder souvent à des éléments via leurs clef, mais c'est moins pratique si tu dois parcourir tous les éléments...
Il serait plus pratique de se créer une classe "Mesure" regroupant les données que l'on veut collecter (date, température).
Du coup si tu ne fais que parcourir les données, une List<Mesure> pourrait s'avérer plus pratique.
Maintenant si tu as besoin de conserver l'association via une clef, tu peux utiliser une SortedMap<LocalDate,Mesure>, que tu pourras toujours parcourir sans rien perdre du tout...
a++
Je suis tout de même contraint d'utiliser un Comparator puisque je souhaite récupérer les couples(date,temperature) des 10 jours les plus chauds de l'année 2014.De plus une grande partie des objets de base sont déjà Comparable, donc tu n'as pas à créer de Comparator tant que tu restes sur l'ordre "naturel" :
Merci encore pour tous vos retours particulièrement enrichissant; je continue ce passionnant exercice qui me permet d'apprendre énormément sur la conception ... et mes erreurs.
a+
J'aurai souhaité avoir une précision.
retourne une vue des valeurs de la Map ce qui entraine qu'en faisant
Code java : Sélectionner tout - Visualiser dans une fenêtre à part List<Float> valueList = new ArrayList<>(tMapTemperatures.values());
les valeurs des températures ne sont pas insérées dans la liste ... donc ma liste reste vide et je ne compare sur rien.
Code java : Sélectionner tout - Visualiser dans une fenêtre à part valueList.addAll(tMapTemperatures.values());
Comment alimenter la liste? Faudrait-il récupérer la valeur temperature de la Map dans le entrySet de la boucle for?
Il n'y a pas de problème avec ce genre de code.
Le problème doit venir d'ailleurs...
a++
Effectivement le problème vient d'ailleurs ... il s'agit derechef d'un problème de conception (j'apprends encore et encore ... c'est génial).
En fait dans cette conception les valeurs récupérées de la Map ne me permettront pas d'utiliser le Comparator pour faire "sortir" les données voulues.
Nouvelle approche :
- Créer une classe TemperatureCoparator (ce qui est dejà fait) :
-- contenant un attribut mesure de type Map<LocalDate,Float> et un constructeur avec comme argument mesure
-- la méthode compare reste "sensiblement" la même ... mais cette fois ci je compare sur les clés dede la Map
Code java : Sélectionner tout - Visualiser dans une fenêtre à part mesure.get(o1)
Je continue dans cette voie et je vous tiens au courant.
a++
Voici ce que cela me donne, sachant que le traitement à l'intérieur du Comparator est à finaliser (mais c'est un premier jet).
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public Map<LocalDate, Float> genererTemperatures10joursPlusChaud() { // Parcours sur les dates, tant qu'on est sur la même année pour récupérer tous les jours de l'année for (LocalDate jour = firstDay; jour.getYear() == YEAR; jour = jour.plusDays(1)) { // S'occuper de récupérer les températures Float temperatures = (rand.nextInt(2 * (MAX - MIN)) + 1 + 2 * MIN) / 2f; // Alimenter la TreeMap hMapTemperatures.put(jour, temperatures); } tMapTemperatures.putAll(hMapTemperatures); System.out.println(tMapTemperatures); return tMapTemperatures; } /** * Classe implémentant l'interface Comparator */ class TemperatureComparator implements Comparator<LocalDate> { Map<LocalDate, Float> mesure; public TemperatureComparator(Map<LocalDate, Float> mesure) { this.mesure = mesure; } @Override public int compare(LocalDate o1, LocalDate o2) { return (mesure.get(o1) >= mesure.get(o2) ? -1 : (Objects.equals(mesure.get(o2), mesure.get(o1)) ? 0 : 1)); } }
Ce code fonctionne correctement, ce qu'il me manque c'est de récupérer uniquement les 10 premières valeurs les plus chaudes ... car comme tel je récupère toutes les valeurs.
Voici ce que cela donne en créant un itérateur pour parcourir les 10 premiers éléments de la TreeMap :
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Integer index = 0; Iterator entries = tMapTemperatures.entrySet().iterator(); while (entries.hasNext() && index < 10) { Map.Entry thisEntry = (Map.Entry) entries.next(); Object date = thisEntry.getKey(); Object temperature = thisEntry.getValue(); System.out.println(date + " : " + temperature + " °C"); index++; }
Autre question :
Comment procéderiez-vous pour générer la liste des températures pour le mois le plus chaud de l'année 2014?
Je pensais récupérer la somme des températures de chaque mois de l'année 2014 puis de comparer chaque mois l'un par rapport à l'autre.
Qu'en pensez-vous?
Merci d'avance.
Transact.
Qu'est ce que le mois le plus chaud de l'année ? le mois qui contient le jour le plus chaud ou le mois dont la moyenne des températures est la plus élevée ?
Attention, si tu récupères la somme, les mois n'ont pas tous le même nombre de jours. Par exemple, s'il a fait 30° tous les jours du mois de juin (30° de moyenne), alors qu'il a fait 29° tous les jours de juillet sauf un jour à 32° (29,1°) de moyenne, ta méthode va considérer que juillet a été plus chaud que le mois de juin, alors que ce n'est pas le cas en moyenne.
En fait, cela dépend de la définition que tu fais du mois le plus chaud de l'année, d'où ma première question. Une fois que tu auras défini le mois le plus chaud, la recherche de ce dernier sera toute simple.
Au final, ça ne change pas grand chose, au lieu de comparer la somme des températures de chacun des mois, tu compares la moyenne des températures de chacun des mois.
Oui devyan, effectivement l'API de Java mentionne ceci :
Mais je suis resté sur les différents type de retour -1,0 ou 1.
Code Java : Sélectionner tout - Visualiser dans une fenêtre à part public final class Float extends Number implements Comparable<Float>
Pour répondre à benratti, je souhaiterai le mois dont la moyenne des températures est la plus élevée.
Il n'empêche que :
ne donne pas la même résultat que :
Code : Sélectionner tout - Visualiser dans une fenêtre à part mesure.get(o1) >= mesure.get(o2)
Dans le premier cas tu compares des pointeurs alors que dans le second tu compares les valeurs.
Code : Sélectionner tout - Visualiser dans une fenêtre à part mesure.get(o1).floatValue() >= mesure.get(o2).floatValue()
devYan.
Tu as sans doute raison, cependant l'IDE Netbeans me surligne en jaune cette ligneen me disant Unnecessary unboxing.
Code java : Sélectionner tout - Visualiser dans une fenêtre à part mesure.get(o1).floatValue()
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager