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

Langage Java Discussion :

Enumération : recherche sur base de la valeur


Sujet :

Langage Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Points : 40
    Points
    40
    Par défaut Enumération : recherche sur base de la valeur
    Bonjour,
    Voici mon énumération :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public static enum StructureCompte { compteBelge(0), compteEtranger(1), ibanBelge(2), ibanEtranger(3);
            private int value;
    	StructureCompte(int val)
    	{
    	    value = val;
    	}
    	public int getValue()
    	{
    	    return value;
    	}
    };
    Je sais que je pourrais me passer des détails et me limiter à citer les libellés dans ce cas, mais là n'est aps ma question

    Je voudrais pouvoir retrouver l'élément de l'énumération à partir de sa valeur et pour le moment, je n'ai trouvé qu'une solution : passer par une boucle :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int struct = Integer.parseInt(line.substring(1,2));
    for (StructureCompte enumItem : StructureCompte.values()) {
    	if (enumItem.getValue() == struct) {
    		solde.setStructureCompte(enumItem);
    		structureCompte = enumItem;
    		break;
    	}
    }
    Ce n'est pas spécialement propre, donc j'aimerais savoir s'il existe un moyen de faire ça en un seul appel à une méthode.

    Merci

  2. #2
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par crawling5 Voir le message
    Ce n'est pas spécialement propre, donc j'aimerais savoir s'il existe un moyen de faire ça en un seul appel à une méthode.
    Le plus simple serait de coder cette méthode dans ton enum, par exemple :
    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
    public static enum StructureCompte {
    	compteBelge(0), compteEtranger(1), ibanBelge(2), ibanEtranger(3);
     
    	private final int value;
     
    	StructureCompte(int val) {
    		value = val;
    	}
     
    	public int getValue() {
     
    		return value;
    	}
     
    	public static StructureCompte valueOf(int enumValue) {
    		for (StructureCompte compte : StructureCompte.values()) {
    			if (compte.value==enumValue) {
    				return compte;
    			}
    		}
    		throw new IllegalArgumentException("No enum const for value " + enumValue );
    	}
    };
    A noter que je te conseille de mettre le champ value en final afin d'éviter toutes erreurs...




    Sinon si tes valeurs sont ordonnées sans blanc et commençant par zéro, tu peux tout simplement utiliser l'ordinal de l'enum :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static enum StructureCompte {
    	compteBelge, compteEtranger, ibanBelge, ibanEtranger;
     
     
    	public static StructureCompte valueOf(int enumValue) {
    		try {
    			return StructureCompte.values()[enumValue];
    		} catch (ArrayIndexOutOfBoundsException e) {
    			throw new IllegalArgumentException("No enum const for value " + enumValue, e );
    		}
    	}
    };
    a++


    PS : En général selon les conventions de nommage, on utiliser seulement des majuscule pour le nom des valeurs d'une enum (compteBelge COMPTE_BELGE).

  3. #3
    Membre chevronné
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Novembre 2005
    Messages : 1 312
    Points : 2 011
    Points
    2 011
    Par défaut
    Ben au pire ta boucle, tu la fait au sein d'une méthode que tu ajoute dans ton enum :

    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
     
    public static enum StructureCompte {
            compteBelge(0), compteEtranger(1), ibanBelge(2), ibanEtranger(3);
     
            private int value;
     
            StructureCompte(int val)
            {
                value = val;
            }
     
            public int getValue()
            {
     
                return value;
            }
     
            public static StructureCompte valueOf(int value){
               StructureCompte result =null;
               for (StructureCompte enumItem : StructureCompte.values()) {
                 if (enumItem.getValue() == value) {
                     result = enumItem;
                     break;
                 }
               }
               if (result==null) throw new IllegalArgumentException("No value corresponding with " + value);
               return result; 
           }
        };
    Pis tu l'utilise cette méthode comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    StructureCompte structureCompte =  StructureCompte.valueOf(2);
    System.out.println(structureCompte); //affiche ibanBelge



    Edit: grillé.

    -"Tout ça me paraît très mal organisé. Je veux déposer une réclamation. Je paye mes impôts, après tout!"
    -"JE SUIS LA MORT, PAS LES IMPÔTS! MOI, JE N'ARRIVE QU'UNE FOIS".

    Pieds d'argile (1996), Terry Pratchett 1948 - 2015
    (trad. Patrick Couton)

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    D'accord, je vais faire comme ça, même si j'aurais préféré une méthode utilitaire

    Pour le nommage, je l'avais vu sans majuscule, donc je n'en avais pas mis. Mais merci pour l'info.
    Concernant le fait de ne faire que lister les éléments, comme je l'avais dit, je le sais que dans ce cas-ci, ça suffirait

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    Je viens de trouver une autre solution qui évite de recopier la méthode dans chaque énumération.

    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
     
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
     
    public class EnumUtil {
     
    	public static <T>T findEnumByValue(Class<T> classe, Object value) {
    		try {
                            if (!classe.isEnum()) {
    				throw new IllegalArgumentException("La classe spécifiée n'est pas une énumération");
    			}
    			Method method = classe.getMethod("values");
    			Enum<?>[] values = (Enum<?>[])method.invoke(classe);
    			for (Enum<?> item : values) {
    				method = item.getClass().getMethod("getValue");
    				Object itemValue = method.invoke(item);
    				if (value.equals(itemValue)) {
    					return classe.cast(item);
    				}
    			}
    		} catch (SecurityException e) {
    			throw new ClassCastException("Impossible d'invoquer la méthode 'getValue()'");
    		} catch (IllegalArgumentException e) {
    			throw new ClassCastException("Impossible d'invoquer la méthode 'getValue()'");
    		} catch (NoSuchMethodException e) {
    			throw new ClassCastException("Impossible d'invoquer la méthode 'getValue()'");
    		} catch (IllegalAccessException e) {
    			throw new ClassCastException("Impossible d'invoquer la méthode 'getValue()'");
    		} catch (InvocationTargetException e) {
    			throw new ClassCastException("Impossible d'invoquer la méthode 'getValue()'");
    		}
    		throw new IllegalArgumentException("Aucun élément de l'énumération " + classe.getName() + " ne correspond à la valeur " + value);
    	}
    }
    Cette méthode fonctionne pour toutes vos énumérations. La seule restriction est que vos énumérations doivent contenir une méthode getValue() si elles ont des valeurs "particulières".


    Maintenant, si vous voyez des points à améliorer, je suis à l'écoute

  6. #6
    Expert éminent sénior
    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
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par crawling5 Voir le message
    Maintenant, si vous voyez des points à améliorer, je suis à l'écoute
    • Utilises le paramètrage <T extends Enum<T>> à la place de <T>. Cela permet d'empêcher l'utilisation de la méthode avec autre chose qu'une enum en provoquant une erreur de compilation si c'est mal utilisé.
    • Utilises la méthode Class.getEnumConstants() plutôt que d'appeler values() par reflection...
    • Déplaces le getMethod("getValue") avant la boucle : cela ne sert à rien de le faire à chaque itération de la boucle.
    • Evites d'ignorer les exceptions, car cela pourrait te jouer de mauvais tour (comme par exemple ne pas comprendre que l'élément n'est pas trouvé parce que tu n'as pas implémenté la méthode getValue()...). Dans ces cas là je te conseille fortement de remonter une nouvelle exception qui englobe la précédente



    Cela donnerait quelque chose comme cela :
    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
    	public static <T extends Enum<T>> T findEnumByValue(Class<T> enumType, Object value) {
    		try {
    			Method method = enumType.getMethod("getValue");
     
    			for (T item : enumType.getEnumConstants()) {
    				Object itemValue = method.invoke(item);
    				if (value.equals(itemValue)) {
    					return item;
    				}
    			}
    		} catch (Exception e) {
    			throw new IllegalArgumentException("findEnumByValue() failed", e);
    		}
    		throw new IllegalArgumentException("Aucun élément de l'énumération " + enumType.getName() + " ne correspond à la valeur " + value);
    	}
     
    	public static <T extends Enum<T>> T findEnumByOrdinal(Class<T> enumType, int ordinal) {
    		try {
    			return enumType.getEnumConstants()[ordinal];
    		} catch (ArrayIndexOutOfBoundsException e) {
    			throw new IllegalArgumentException("Aucun élément de l'énumération " + enumType.getName() + " ne correspond à la valeur ordinale " + ordinal, e);
    		}
    	}

    Une autre solution serait d'utiliser une interface décrivant la méthode getValue() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public interface EnumIdentifier<V> {
    	public V getValue();
    }
    Interface qui devra être implémenter par tes enums :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    enum StructureCompte implements EnumIdentifier<Integer> {
        compteBelge(0), compteEtranger(1), ibanBelge(2), ibanEtranger(3);
     
        private int value;
     
        StructureCompte(int val) {
            value = val;
        }
     
        public Integer getValue() {
            return value;
        }
    }
    Ce qui fait que tu pourras utiliser cette méthode un peu plus typesafe (la méthode getValue() sera forcément présente ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public static <V, T extends Enum & EnumIdentifier<V>> T findEnumByValue(Class<T> enumType, V value) {
    		for (T item : enumType.getEnumConstants()) {
    			if (value.equals(item.getValue())) {
    				return item;
    			}
    		}
    		throw new IllegalArgumentException("Aucun élément de l'énumération " + enumType.getName() + " ne correspond à la valeur " + value);
    	}
    a++

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    47
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 47
    Points : 40
    Points
    40
    Par défaut
    J'ai choisi ta solution avec l'interface et ça fonctionne parfaitement.
    Je ne connaissais pas cette possibilité d'écriture au niveau des types de retour.

    Merci beaucoup.

  8. #8
    Nouveau membre du Club
    Profil pro
    Consultant informatique
    Inscrit en
    Novembre 2007
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 32
    Points : 32
    Points
    32
    Par défaut Quand c'est déjà tout fait . . .
    Bonjour,

    il faut juste appeler la méthode ordinal() et tu auras ce que tu cherches.

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 14/06/2010, 02h39
  2. Réponses: 0
    Dernier message: 28/05/2010, 20h08
  3. Moteur de recherche sur base de données
    Par GiZoX dans le forum Général Java
    Réponses: 3
    Dernier message: 06/04/2009, 17h34
  4. Moteur de recherches sur base Mysql
    Par Kenya dans le forum Dreamweaver
    Réponses: 0
    Dernier message: 13/08/2008, 20h01
  5. requete sql de recherche sur base access
    Par donhatem dans le forum Langage SQL
    Réponses: 9
    Dernier message: 22/07/2008, 23h05

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