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 :

Adressage d'éléments d'une array


Sujet :

Collection et Stream Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut Adressage d'éléments d'une array
    Bonjour,
    Je pense que je vieillis ...
    En guise d'objet à données d'entrées pour mon programme, j'ai de grandes arrays à plusieurs types d'éléments, du genre :
    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
        final static Object[] formTarif_Belgacom =
        {  
            new Object[]
            {   
                FormTarif_Libellés_0903.get_FormTarif_Libellés(),  // static
                new String( "<html><font color=green>Belgacom</font></html>" ),
                new Object[]
                {   new String( "2010 mai" ),
                    new String( "2010 mei" )
                },
                null,
                null,
                new BigDecimal( 2.345 ),
                new BigDecimal( 1.234 )
            },
            // Ensemble de données tarifaires propres au 10 oct.
            new Object[]    // [0] : 2010 Mai
            {   new Object[] // District A
                {   new Object[] // 
                    {   new Object[] // Aanbod
                        {   new Object[]
                            {   new String( "Contrat de 1 an" ),
                                new String( "1 jaar contract" )
                            },
                            new Boolean(Prix.indexés.enBooléen()),
                            new Object[]
                            {   new Object[]
                                {   null,
                                    new Object[] // [0] : Normaal
                                    { new BigDecimal( 50.00 ),
                                      new BigDecimal(  9.91 )
                                    },
                                    new Object[] // [1]
                                    { new BigDecimal( 50.00 ),
                                      new BigDecimal( 12.89 ),
                                      new BigDecimal(  5.69 )
                                    },
                                    new Object[] // [2]
                                    { new BigDecimal( 50.00 ),
                                      new BigDecimal(  4.88 )
                                    }
                                }
                            }
                        }
                    },
                    new Object[] // Contributions
                    {   new BigDecimal( 0.303 )
    ...
    Soit des arrays imbriquées, de longueurs d'éléments variables et de types d'éléments différents.

    J'ai aussi une très grande fonction réentrante ajoutant des Strings de libellés à chaque élément de ces objets de données d'entrée, en supprimant certains éléments, ... du genre :
    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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
        private ArrayList<Object> assocLibellésAuxItemsDonnées(Object[] chaîneSource)
        {   byte nbreEléments = (byte) chaîneSource.length;
            // Pas de multiples threads d'accès ni de modification structurelle.
            ArrayList<Object> chaîneCible =
                    new ArrayList<Object>(nbreEléments);
            Object descendant = null;
     
            boucleExtérieure:
            for (int index = 0; index < nbreEléments; index++)
            {   // Ajout du String se trouvant dans le fichier de libellés.
                // Object car élément est de type String, Boolean, Object[], BigDecimal ou null
                Object élément = chaîneSource[index];
                // ifs et switch-cases imbriqués de ±5.600 lignes !
                if (élément instanceof String)
                {   switch (nivRéentr[1])
                    { case 0:   // nivRéentr[1]     // Il n'y a pas de String à ce niveau 0.
                        break;
                      case 1:   // nivRéentr[1]
                        switch (indexCheminArbor[0])
                        { case 0:  // indexCheminArbor[0] / nivRéentr[1]=1
                            // Données identiques pour tous les sous-ensembles inclus dans l'Object indexCheminArbor[0] = 1.
                            switch (indexCheminArbor[1])
                            { case 0:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                // FormTarif_Libellés_YYMM
                                break;
                              case 1:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                // <html><font color=green>Belgacom</font></html>
                                dénomFournis = (String) élément;
                                // Libellé déjà fourni en première position dans chaque 'new Object[]' de 'SommaireFormTarif_ComposTarif_YYMM'.
                                continue boucleExtérieure;
                              case 2:
                                // Au cas où String unique (pas Object de deux strings de deux langues.
                                // Mois d'application du tarif - "2010 mai"
                                moisDApplication = (String) élément;
                                break;
                              case 3:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                // Dénominations de formules tarifaires et les statuts
                                formTarif_DénomDsFichDEntrée[0] = (String) élément;
                                break;
                              case 4:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                // Dénominations de formules tarifaires et les statuts
                                break;
                              case 5:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                break;
                              case 6:  // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                break;
                              default: // indexCheminArbor[1] / nivRéentr[1]=3 / indexCheminArbor[0]=0
                                break;
                            }
                            break;
                          case 1:  // indexCheminArbor[0] / nivRéentr[1]=1
                            // Ensemble de données tarifaires propres au YYMM.
                            // Il n'y a pas de String à ce niveau indexCheminArbor[0]=1.
                            break;
                          default: // indexCheminArbor[0] / nivRéentr[1]=0
                            break;
                        }
                        break;
                      case 2:   // nivRéentr[1]
                        switch (indexCheminArbor[0])
                        { case 0:  // indexCheminArbor[0] / nivRéentr[1]=2
    ...
                if (élément instanceof Object)
                {   switch (nivRéentr[1])
                    { case 0:   // nivRéentr[1]
                        switch (indexCheminArbor[0])
                        { case 0:  // indexCheminArbor[0] / nivRéentr[1]=0
                            // Entrer dans l'Object '0' de nivRéentr[1]=0 :
                            break;
                          case 1:  // indexCheminArbor[0] / nivRéentr[1]=0
                            // Ensemble de données tarifaires propres au YYMM.
                            // Entrer dans l'Object '1' de nivRéentr[1]=0.
                            break;
                          default: // indexCheminArbor[0] / nivRéentr[1]=0
                            break;
                        }
                        break;
                      case 1:   // nivRéentr[1]
                        switch (indexCheminArbor[0])
                        { case 0:  // indexCheminArbor[0] / nivRéentr[1]=1
                            // Entré dans l'objet '0' de nivRéentr[1]=0.
                            // Données identiques pour tous les sous-ensembles inclus dans le 2e Object.
                            switch (indexCheminArbor[1])
                            { case 0:  // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                // Référence vers 'FormTarif_Libellés_1003'
                                formTarif_Libellés = (Object[]) élément;
                                // élément.get_FormTarif_Libellés();
                                chaîneCible.ensureCapacity(nbreEléments + 70);  // Pour tous les libellés à ajouter.
                                nivRéentr[0] = nivRéentr[1];
                                indexCheminArbor[nivRéentr[1]]++;
                                // Ne pas créer l'Object 'FormTarif_Libellés_1003'.
                                continue boucleExtérieure;
                              case 2:  // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                // Libellé en deux langues : '2010 mai' toujours en un Object de 2 strings.
                                élément = (String) chaîneSource[index][0];
                                break;
                              case 3:  // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                // Dénomination de la formule tarifaire en 2 strings bilingues.
                                break;
                              case 4:  // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                // Statuts d'indexation
                                break;
                              case 8:  // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                // nbreElem_lim = (BigDecimal[])((Object[])((Object[])formTarif_Données[0])[8]).length;
                                break;
                              default: // indexCheminArbor[1] / nivRéentr[1]=1 / indexCheminArbor[0]=0
                                break;
                            }
                            break;
                          case 1:  // indexCheminArbor[0] / nivRéentr[1]=1
    Une douzaine de lignes avant la fin, observez le code problématique
    élément = (String) chaîneSource[index][0];
    En mode de déboguage (en NetBeans), j'observe que l'array "new Object[]" est initialisé comme il se doit avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
                            {   new String( "2010 mai" ),
                    new String( "2010 mei" )
                            },
    Pour mettre en 'élément' l'une des deux valeurs de cette array initialisée, comment dois-je formuler mon code ? Le compilateur-life rouspète :
    "Array required; but java.lang.Object found"
    Remerciements anticipés.

  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
    Bon alors première chose, si vous en avez la possibilité, ce code, à la poubelle. Il viole à peu près toutes les règles de bonne pratique en java et tous les principes d'encapsulation. Il a été codé comme on coderait en C (même pas en C++), sans même connaitre le type "struct".


    Au lieu d'un tableau de bordel (je vois pas d'autre mot), il faut remplacer ça par des objets avec des valeurs bien typées, de données bien identifiées. Là c'est un soupe à l'index et au typecasting, ça va être un casse tête à débugger et à maintenir. Sans parler de l'utilisation de static final pour des données qui sont typiquement variables dans le temps (des prix indexés, ca change à chaque index)

    Quand à votre problème, mis à part qu'il est la conséquence du flou artistique plus haut, le message d'erreur est clair: "chaîneSource" est déclaré comme étant de type Object, pas comme étant de type Tableau de tableau. Si c'est un type tableau de tableau, il faut faire un type casting vers ce type pour pouvoir l'utiliser. Mais franchement, jettez ça à la poubelle et faites du code propre.

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut
    Tchize, merci d'avoir répondu, une fois de plus.
    - Je n'ai jamais beaucoup estimé les étudiants qui, recevant de valables conseils, commencent systématiquement et sans temps suffisant de réflexion à répliquer des excuses au lieu d'abord de digérer ces conseils. J'aurais donc voulu ne pas répondre avec un "oui mais", mais ici, je pense que je peux car ...
    - Principalement : La structure d'objets de classe "Default Mutable Tree Node" que requière un JTree et ses objets associés (Renderer, Editor, Listener ...) ne peut être formée qu'à partir d'un tableau de tableaux de tableaux ... avec autant de niveaux (de profondeur variable) que l'arborescence et la logique le veut.
    - Chaque mois, c'est une trentaine de fichiers de données d'entrée qui s'ajoute dans mon programme. Mon intention originale était de reporter à plus tard le fait de coder ces fichiers de tarifs en XML. Tu me diras que cela ne change en rien le fait que quelque part dans mon programme, une structure (au sens C) ou un objet (sans méthodes) de fusion des données tarifaires avec des libellés (dans une langue et provenant d'une autre structure d'un autre fichier) de chaque item doive se passer, et donc que la création de tarifs mensuels sous forme structurée d'objets doive aussi se produire. J'admets ta critique virulente mais originellement, je pensais aussi que ce code de tableaux de tableaux ... me ferait aboutir plus rapidement à un premier résultat et surtout avec des fichiers et du code moins dispersés et plus concis. Je ne vois toujours pas en quoi ce n'est pas le cas ... comme étape intermédiaire de développement, pour preuve de faisabilité. Surtout : des tas d'objets dans objets (typés) me semblent une explosion en volume de code et plus lourds à maîtriser. J'y pensais, mais le remettais à plus tard si Jtree Default Mutable Tree Node le permet quand même.
    - Je suis à 99 % de clôturer cette étape de programmation. Reculer et refaire ... oui mais plus tard.
    - C'est vrai que j'ai gardé des façons de faire du temps où je développais en C et C++.
    Crois bien que j'étudierai la possibilité de suivre ton conseil dès que possible.

    Mais ma question originelle : Comment coder acceptablement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    élément = (String) chaîneSource[index][0];
    pour référencer l'un des ceux String du tableau "chaîneSource[index]" ?
    (Sans quoi je ne peux pas encore activer "Résolu")

  4. #4
    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
    Mais ma question originelle : Comment coder acceptablement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    élément = (String) chaîneSource[index][0];
    pour référencer l'un des ceux String du tableau "chaîneSource[index]" ?
    Comme je l'ai dit dans mon premier message , il va vous falloir un typecasting puisque dans votre code, chaîneSource est déclaré comme un Object
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    élément = (String) ((String[][])chaîneSource)[index][0];
    Ceci en supposant que chaîneSource est bien un tableau de tableau de String, ce dont je ne puis être sur vu l'illisibilité de la structure.

    Citation Envoyé par Chavadam Voir le message
    - Principalement : La structure d'objets de classe "Default Mutable Tree Node" que requière un JTree et ses objets associés (Renderer, Editor, Listener ...) ne peut être formée qu'à partir d'un tableau de tableaux de tableaux ... avec autant de niveaux (de profondeur variable) que l'arborescence et la logique le veut.
    Non, si vous regardez le howto officiel, a aucun moment il n'est fait usage de tableau de tableau. JTree utilise des objet Node, a vous d'avoir une structure cohérente et facile à lire, et une méthode qui la parcoure pour remplir un DefaultMutableTreeNode via des new et des addChildren. De plus, vu l'aspect "statique" des données, je ne conseillerais pas d'utiliser un MutableNode, pour éviter tout risque de modification. Vous pouvez aussi associer à chaque classe business un wrapper qui en fait un Node, mais ce n'est pas indispensable, le defaultMutableTreeNode pouvant faire l'affaire dans beaucoup de cas. Enfin, si vosu regardez les sources, a aucun moment DefaultMutableTreeNode ne considère que l'Object qu'on lui passe est un tableau.

    Enfin, la structure de données qu'utilise votre programme doit être dirigée par des besoins business (on a un PlanTarifaire, avec des Description, un PrixIndexé, les plans sont groupés par Periode et TypeDeContrat) et non pas par les besoin de votre Modèle swing. Sinon, que se passera-t-il demain lorsque votre boss dira "non finalement, on va plutôt utiliser un combobox". Vous serez bien content d'avoir des structures qui ne sont pas un casse tête à explorer. Votre code contient déjà des switch/case kilométrique, des entiers "magique" et du typecasting dans tous les sens. On en est qu'au prototype et c'est déjà presque impossible à lire.
    J'admets ta critique virulente mais originellement, je pensais aussi que ce code de tableaux de tableaux ... me ferait aboutir plus rapidement à un premier résultat et surtout avec des fichiers et du code moins dispersés et plus concis.
    Premier résultat dont, dès la validation, vous devrez changer la structure de donnée, et tout le code la manipulant. Soit deux fois le travail. Et comme la structure n'as aucun type forcé, vous pouvez dire au revoir aux outils de refactoring de votre IDE. Résultat, pour ne pas perdre de temps on ne le fera pas tout de suite, puis plus tard on aura toujours pas le temps, etc.Au final, le code deviendra presque impossible à manipuler et vous allez hériter de ce monstre. De bonne bases dès le départ, c'est du temps gagné dès le départ ainsi que par la suite quand il faudra modifier le modèle business (et vous n'y couperez pas, il y aura toujours un truc que votre boss / architecte / analyste / client a oublié de mentionner).

    Je vais prendre un exemple tout bête. Demain on vous dit qu'un champ n'a plus une mais trois valeurs. Vous aller devoir le convertir de String en String[]. Dans un tableau d'objet, vous devrez lancer 50 fois le code pour noter tous les endroits où ça plante. Avec des objets, vous allez changer la signature d'une méthode (String getMachin() -> String[] getMachin()) et votre IDE (ou javac) pointera immédiatement tous les endroit où vous l'utilisez et qu'il faut corriger. Avec un bon IDE, le refactoring sera même à 90% automatique.

    Ça ne prend pas plus de temps de créer 4/5 classes englobant le modèle business que le temps que vous prenez à coder les switch case (et les débugger). Mais que de temps gagné par la suite.
    Vous pourrez très bien, pour la démo, coder dans le main ou autre le remplissage vite fait de cette classe avec des données d'exemples(rien n'oblige à avoir maintenant le parsing des données).

    Sérieusement, coder une classe business de 10 champs, avec un IDE, ca prend 2 minutes, tasse de café comprise.


    - Je suis à 99 % de clôturer cette étape de programmation. Reculer et refaire ... oui mais plus tard.
    Aujourd'hui ou demain, vous allez devoir le jeter ce code, et plus vous attendrez, plus ce sera un problème. Ce simple commentaire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    // ifs et switch-cases imbriqués de ±5.600 lignes !
    Résume à lui seul tout votre problème. Vous approchez d'ailleurs fortement de la taille limite que peux avoir le corps d'une méthode en java

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 74
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Par défaut
    Tchize,
    D'accord que mon tableau de tableaux de ... (9 niveaux), résultant de l'agrégation de N tableaux de tableaux de ..., c'est devenu un casse-tête à maintenir ou modifier et ce n'est pas de l'OOL.
    OK pour le "élément = (String)((Object[][])chaîneSource)[index][0];" d'ailleur équivalent à "(String)((Object[])((Object[])chaîneSource)[index])[0]);" Ca marche.
    Ne pas oublier que je suis autodidacte en programmation Java et que ça ne va plus aussi vite, une fois la soixantaine atteinte.
    Maintenant je me réserve du temps à concevoir un business model, suivant ton conseil. Peut-être à plus tard sur une nouvelle discussion concernant l'interface entre un concept OOL de toutes mes formules tarifaires et les Nodes dont a besoin un JTree. (OK; 'Default Mutable Tree Node' ne m'est pas nécessaire)
    Si d'aventure tu avais "sous la main" un URL d'un site offrant un tutoriel ou un bon exemple au sujet de la conception d'un business model et de son interfaçage et indépendance avec des objets tels que JTree, ComboBox, ...
    Grand merci car cela t'a certainement pris du temps à comprendre ma démarche.

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

Discussions similaires

  1. Réponses: 10
    Dernier message: 25/02/2014, 20h22
  2. [VB.NET] Enregistrement des éléments d'une listBox
    Par Hoegaarden dans le forum Windows Forms
    Réponses: 9
    Dernier message: 18/05/2004, 14h48
  3. déplacer un élément d'une table
    Par Sph@x dans le forum Requêtes
    Réponses: 3
    Dernier message: 10/02/2004, 12h12
  4. Réponses: 2
    Dernier message: 11/08/2003, 09h43
  5. Pré-sélectionner un élément d'une combobox
    Par delphim dans le forum Composants VCL
    Réponses: 4
    Dernier message: 17/06/2003, 15h26

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