IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Collection et Stream Java Discussion :

Exercices pratiques, Random, Collection, Map


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné
    Avatar de Rony Rauzduel
    Homme Profil pro
    En formation Architecte logiciel
    Inscrit en
    Décembre 2008
    Messages
    638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : En formation Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 638
    Par défaut Exercices pratiques, Random, Collection, Map
    Bonjour à tous,

    Actuellement je m'initie/perfectionne sur l'étude des containers (Collection/Map) en Java en faisant des exercices et je cherche quelques conseils concernant la méthodologie à adopter pour la résolution de ceux-ci.

    Enoncé : Générer un relevé de températures aléatoirement (comprises entre -10° et 40°) pour chaque jour de l'année 2014 et stocker dans une collection appropriée :
    On aura donc des couples (date,température).

    J'entrevoie brièvement ce qui faut utiliser, par exemple la classe java.lang.Random, la méthode Math.random() de la classe Math du package java.util.

    J'ai mis sur papier la formule mathématique de calcul permettant de générer le relevé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     min+(int)(Math.random()*(max+1-min))+min
    Quelle Map utiliser? SortedMap, HashMap ...

    Je ne suis pas novice en programmation Java ... mais ce que je recherche avant tout est une méthode pour résoudre une problématique.

    Comment procéder ?

    Merci d'avance pour vos conseils.

  2. #2
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Ben il faut quelques réflexes de POO à acquerir.

    La manière dont tu génère l'aléatoire, finalement, ça importe peu dans la question tu fais ce que tu veux. La question se pose du stockage. Que dois tu stocker?

    Une valeur, associé à une date, et vraisemblablement accédé par date. Décompose le problème:

    une valeur:
    • Float
    • Integer
    • classe personnelle "Temperature"
    • autre idée?



    une date:
    • java.util.Date
    • String
    • java.util.Calendar
    • java.time.LocalDate (java 8)


    associé:
    • Map
    • SortedMap
    • Quelle implémentation?


    Une bonne manière de stocker la température, selon moi, c'est Float, L'integer n'est pas assez précis, une classe custom n'est pas facilement justifiable, et je n'ai pas d'autre idée
    pour la date, java.util.Date est compliqué à manipuler et contient aussi des heures, Calendar rajoute en plus une timezone. String a l'inconvénient de te lier à une représentation de la date. Finalement LocalDate semble avoir tous les avantages: indépendant de l'heure et de la timezone, facile à manipuler, pas trop contraint.

    Ce qui nous amènes avec les deux choix faciles:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Map<LocalDate,Float>
    SortedMap<LocalDate,Float>
    triée ou pas triée la map? La maintenir triée, ça a un coût, tant en terme de mémoire que de temps CPU. As-tu besoin de parcourir les dates dans l'ordre? Il y a fort à parier que tu voudra afficher un tableau trié de mesure. Donc le SortedMap se justifie probablement. Pour l'implémentation, plus qu'à faire ton choix dans ce qui est proposé, et il n'y a que TreeMap de vraiment disponible. On sent bien à lire le nom de "ConcurrentSkipListMap" que ça ne colle pas trop au besoin

  3. #3
    Membre chevronné
    Avatar de Rony Rauzduel
    Homme Profil pro
    En formation Architecte logiciel
    Inscrit en
    Décembre 2008
    Messages
    638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : En formation Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 638
    Par défaut
    Dans un premier temps merci pour tes conseils avisés tchize_.
    Les concepts de POO s'acquièrent en pratiquant ce genre d'exercice, et c'est le pourquoi de ma pratique.
    J'utilise Java 7 donc je devrai me passer de LocalDate, je pensai utiliser GregorianCalendar ou JodaTime qu'en penses-tu?

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 582
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 582
    Par défaut
    GregorianCalendar est un peu lourd en mémoire et en temps de calcul. Dans ton cas très précis ce n'est pas à proprement parler un problème, mais dans le cas général tu ne voudrais jamais indexer une Map avec des GregorianCalendar. Il y a aussi le fait que c'est une classe mutable et faite pour être mutée, ce qu'il faut éviter de mettre comme clés dans des Map, car le mécanisme de Map ne fonctionne plus si on modifie les clés qu'elle contient après les avoir insérées.

    Joda-Time est très bien, mais c'est une bibliothèque tierce, que tu vas devoir ajouter. Et puis il va donc falloir décider quelle classe tu utilises dans ta Map. (Oui, bon, laquelle prendre est évident, mais c'est là l'exercice, hein.)
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre chevronné
    Avatar de Rony Rauzduel
    Homme Profil pro
    En formation Architecte logiciel
    Inscrit en
    Décembre 2008
    Messages
    638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : En formation Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 638
    Par défaut
    Ola!Ola! ... j'ai déjà "du mal" à agréger toutes ses informations pour résoudre cet exercice.
    Entendu pour GregorianCalendar et c'est noté dans le cadre professionnel mais pour cet exercice aucune mutation ne sera effectuée donc je partirai sur du GregorianCalendar.
    Merci pour cette information.

  6. #6
    Membre chevronné
    Avatar de Rony Rauzduel
    Homme Profil pro
    En formation Architecte logiciel
    Inscrit en
    Décembre 2008
    Messages
    638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : En formation Architecte logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2008
    Messages : 638
    Par défaut
    Voici le début de mon code mais je planche sur le reste
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    public final class Temperature {
        private final static int YEAR = 2014;
        public static void main(String[] args) {        
            SortedMap<GregorianCalendar, Float> tMapTemperatures = new TreeMap<>();
            Calendar dates = new GregorianCalendar(YEAR, Calendar.MONTH, Calendar.DAY_OF_WEEK);
            DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
     
        }    
    }

  7. #7
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par tchize_ Voir le message
    Avec ton code, tout le monde va partager le même calendrier qui aura comme valeur celle initialisée au dernier appel getCalendrier. Ce n'est pas un bon plan. Pourquoi la méthode que tu avais entamée avec le contructeur ne te convient pas?
    Gros +1 !


    Citation Envoyé par transact Voir le message
    Entendu pour GregorianCalendar et c'est noté dans le cadre professionnel mais pour cet exercice aucune mutation ne sera effectuée donc je partirai sur du GregorianCalendar.
    Et paf ! T'es tombé dans le piège.
    Tu annonçais fièrement ne faire aucune mutation sur les GregorianCalendar, mais c'est pile poil ce que tu fais avec ta méthode getCalendrier() : tu retournes une unique instance partagé par tout le monde.
    Du coup toutes les variables obtenu via cette méthode seront toujours égales à la dernière valeur indiqué.



    Lorsqu'on veut utiliser un objet en clef d'une Map, il est impératif d'utiliser un objet immuable.
    Se contenter de dire "je ne vais pas le modifier" ne suffit pas, car l'erreur de manip surviendra toujours et cela engendrera des bugs incompréhensibles !!!


    Si tu ne peux vraiment pas utiliser Java 8 ou Joda-Time, le plus simple serait de se créer une classe "Date" immuable...
    Pour un usage basique c'est pas bien méchant à faire :
    Code : 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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    /**
     * Date GMT (year-month-day)
     */
    public final class MyDate implements Comparable<MyDate> {
     
    	private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
     
    	private final long timestamp;
     
    	private MyDate(long timestamp) {
    		this.timestamp = timestamp;
    	}
     
    	public static MyDate of(int year, int month, int day) {
    		try {
    			// Contrairement à son nom getInstance() crée une nouvelle instance :
    			Calendar cal = Calendar.getInstance(GMT);
    			// On défini la date (à 12:00) :
    			cal.clear();
    			cal.set(Calendar.HOUR_OF_DAY, 12);
    			cal.set(Calendar.YEAR, year);
    			cal.set(Calendar.MONTH, month-1);
    			cal.set(Calendar.DAY_OF_MONTH, day);
     
    			// On désactive le mode Lenient
    			// (pour générer une erreur si la date est fausse)
    			cal.setLenient(false);
     
    			return new MyDate(cal.getTimeInMillis());
    		} catch (Exception e) {
    			throw new IllegalArgumentException(String.format("%04d-%02d-%02d", year, month, day), e);
    		}
    	}
     
    	@Override
    	public int compareTo(MyDate o) {
    		return Long.compare(this.timestamp, o.timestamp);
    	}
     
    	@Override
    	public boolean equals(Object obj) {
    		if (obj==this) return true;
    		if (obj instanceof MyDate) {
    			return this.timestamp == ((MyDate)obj).timestamp;
    		}
    		return false;
    	}
     
    	@Override
    	public int hashCode() {
    		// basé sur le hashCode() de Long :
    		return (int)(this.timestamp ^ (this.timestamp >>> 32));
    	}
     
    	public String toString() {
    		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    		sdf.setTimeZone(GMT);
    		return sdf.format(this.timestamp);
    	}
    }
    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	MyDate january1st = MyDate.of(YEAR, 1, 1);
    	MyDate noel = MyDate.of(YEAR, 12, 25);
     
    	MyDate badDate = MyDate.of(YEAR, 2, 30); // IllegalArgumentException

    Maintenant JodaTime (ou LocalDate de JAva 8) serait bien plus adéquate car bien plus fonctionnelle !


    a++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Collections] map ordonnée + accès par indice
    Par jedimind dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 11/11/2011, 12h43
  2. Réponses: 6
    Dernier message: 27/04/2011, 21h44
  3. [Entité-Association] Demande d'exercice pratique avancé pour conception d'ERD Merise
    Par patmaba dans le forum Schéma
    Réponses: 4
    Dernier message: 29/04/2009, 13h34
  4. Réponses: 4
    Dernier message: 07/02/2008, 12h34
  5. exercices "classe et collections" vb
    Par aabdel dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 30/05/2007, 18h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo