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 :

StringIndexOutOfBoundsException, trim et equals


Sujet :

Langage Java

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 214
    Par défaut StringIndexOutOfBoundsException, trim et equals
    Bonjour à tous.

    Alors oui je sais, le titre de ce sujet n'est pas très explicite mais c'est assez complexe de résumer en 1 ligne.

    Voici mon problème, j'ai une StringIndexOutOfBoundsException avec comme valeur passée à un substring -1, jusque là c'est possible.

    Mais voici le code concerné:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		for (String word : words) {
    			if (!word.trim().equals("")) {
    				String lastChar = word.substring(word.length()-1);
    				if (lastChar.equals(".") || lastChar.equals("'")) {
    					inputStreet += word;
    				} else {
    					inputStreet += word+ " ";
    				}
    			}
    		}
    La ligne concernée semble être if (!word.trim().equals("")) mais j'imagine que c'est plutôt celle du dessous.
    Seulement... comment pourrais-je avoir un length = 0 si je suis passé dans la condition?

    Je soupçonne un problème de charset (words provient d'une saisie d'utilisateur) mais j'aimerai en être vraiment certain.

    Merci d'avance!

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    La classe String est immuable, quand tu appel trim() le string word ne change pas mais tu as une autre référence avec laquelle tu compare avec ""
    fallait faire plutôt

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    for (String word : words) {
                            if (word == null) continue; //faire attention au NullPointerException
                            word = word.trim(); // <-- C'EST CE QUI MANQUAIT
    			if (!word.equals("")) {
    				String lastChar = word.substring(word.length()-1);
    				if (lastChar.equals(".") || lastChar.equals("'")) {
    					inputStreet += word;
    				} else {
    					inputStreet += word+ " ";
    				}
    			}
    		}
    A+-

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 214
    Par défaut
    Je suis bien d'accord que j'ai une autre référence... mais en quoi cela change-t'il le contenu?

    Oui effectivement, je peux avoir une différence de longueur entre word et word.trim()... mais si word.trim() n'est pas égal à une chaine vide, word non plus!

  4. #4
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 688
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 688
    Par défaut
    Si par exemple word vaut " " alors word.trim() vaut bien "" et ne passera pas dans ton if.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 214
    Par défaut
    Citation Envoyé par Uther Voir le message
    Si par exemple word vaut " " alors word.trim() vaut bien "" et ne passera pas dans ton if.
    En effet oui... c'est bien logique
    Mais ça n'explique pas le soucis ici

  6. #6
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 688
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 688
    Par défaut
    Si tu as une chaine vide qui passe dans ton if, alors word.length()-1 vaudra -1 et donc logiquement, il y a un StringIndexOutOfBoundsException.

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 214
    Par défaut
    Citation Envoyé par Uther Voir le message
    Si tu as une chaine vide qui passe dans ton if, alors word.length()-1 vaudra -1 et donc logiquement, il y a un StringIndexOutOfBoundsException.
    Oui et c'est pourquoi la condition "if (!word.equals("")) {" a été placée plus haut depuis le début.

  8. #8
    Membre actif
    Inscrit en
    Juillet 2003
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 46
    Par défaut
    j'ai testé ce code rapidement et je n'obtiens aucune erreur. (avec vide, espace , mot standard et uniquement un retour chariot).

    peux tu nous donner la stack trace? ou alors la liste de mots que tu essaye de traiter.

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    214
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2004
    Messages : 214
    Par défaut
    Citation Envoyé par ultimax Voir le message
    j'ai testé ce code rapidement et je n'obtiens aucune erreur. (avec vide, espace , mot standard et uniquement un retour chariot).

    peux tu nous donner la stack trace? ou alors la liste de mots que tu essaye de traiter.
    Je n'ai pas de liste de mot étant donné que c'est l'utilisateur qui encode les possibilités. C'est pourquoi je pensais à un problème de charset: l'utilisateur a peut-être copié du texte d'un document word ou autre.
    En fait, je me dis que c'est une explication qui peut-être cohérente:
    La méthode length() d'un String ne compte que les caractères unicode reconnus par Java et donc me renvoie 0. Tandis que la méthode equals() se base sur par exemple l'espace mémoire pris.

    Quoiqu'il en soit, j'ai modifié le code et la condition en utilisant les StringUtils mais je posais la question ici parce que ça m'intrigue ^^

    Voici la stack:

    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
    15:32:48,080 ERROR [ExceptionMappingInterceptor] String index out of range: -1
    java.lang.StringIndexOutOfBoundsException: String index out of range: -1
    at java.lang.String.substring(String.java:1932)
    at java.lang.String.substring(String.java:1905)
    at be.ict.core.util.AddressUtil.replaceCharacters(AddressUtil.java:142)
    at be.ict.core.util.AddressUtil.getSignificantsPartsOfStreet(AddressUtil.java:110)
    at be.ict.core.util.AddressUtil.getSignificantsPartOfStreet(AddressUtil.java:89)
    at be.ict.core.services.DefaultAddressMatcherImpl.matchAddressFields(DefaultAddressMatcherImpl.java:351)
    at be.ict.core.services.DefaultAddressMatcherImpl.matchMunicipality(DefaultAddressMatcherImpl.java:125)
    at be.ict.core.services.DefaultAddressMatcherImpl.match(DefaultAddressMatcherImpl.java:62)
    at be.ict.web.actions.secure.AddressAction.match(AddressAction.java:188)
    at be.ict.web.actions.secure.AddressAction.processFormSubmission(AddressAction.java:132)
    at be.ict.web.actions.AbstractFormAction.execute(AbstractFormAction.java:42)
    at sun.reflect.GeneratedMethodAccessor9277.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)

  10. #10
    Membre actif
    Inscrit en
    Juillet 2003
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2003
    Messages : 46
    Par défaut
    je ne vois pas d'ou viens le problème

    mais bon tu peux le résoudre comme cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    for (String word : words) {
    			if (word!= null && word.trim().length()>0) { // check size instead of compare to ""
    				String lastChar = word.substring(word.length()-1);
    				if (lastChar.equals(".") || lastChar.equals("'")) {
    					inputStreet += word;
    				} else {
    					inputStreet += word+ " ";
    				}
    			}
    		}

  11. #11
    Modérateur
    Avatar de dinobogan
    Homme Profil pro
    ingénieur
    Inscrit en
    Juin 2007
    Messages
    4 073
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France

    Informations professionnelles :
    Activité : ingénieur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 4 073
    Par défaut
    Citation Envoyé par k o D Voir le message
    Quoiqu'il en soit, j'ai modifié le code et la condition en utilisant les StringUtils mais je posais la question ici parce que ça m'intrigue ^^
    Tu vas devoir ajouter des logs pour tracer ce que l'utilisateur entre.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java
    Que la force de la puissance soit avec le courage de ta sagesse.

  12. #12
    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
    Citation Envoyé par k o D Voir le message
    En fait, je me dis que c'est une explication qui peut-être cohérente:
    La méthode length() d'un String ne compte que les caractères unicode reconnus par Java et donc me renvoie 0. Tandis que la méthode equals() se base sur par exemple l'espace mémoire pris.
    Ce n'est pas comme ça que ça marche. Grosso-modo un String est fait d'un char[]. La méthode length() renvoie la taille de ce char[], et la méthode equals() vérifie que les char[] ont la même taille et que chaque char, à chaque emplacement, est le même.

    En réalité c'est un peu moins simple, mais toujours est-il qu'une distortion entre length() et equals() serait un bug de la JVM, bug que je n'observe pas.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre chevronné
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Par défaut
    +1 pour ultimax, j'allais proposer la même chose

Discussions similaires

  1. [debutant][struts]: utilisation du tag <logic:equal ...&g
    Par sleepy2002 dans le forum Struts 1
    Réponses: 13
    Dernier message: 23/11/2006, 17h04
  2. [STRUTS] Tag Equal, comparer deux variables
    Par logica dans le forum Struts 1
    Réponses: 2
    Dernier message: 04/06/2004, 12h01
  3. [ Struts ] plusieurs conditions avec equal?
    Par njac dans le forum Struts 1
    Réponses: 7
    Dernier message: 04/06/2004, 09h04
  4. Equivalent de la fonction trim
    Par PCHINK dans le forum C
    Réponses: 6
    Dernier message: 21/03/2004, 18h02
  5. trim
    Par divableue dans le forum Langage SQL
    Réponses: 2
    Dernier message: 26/11/2003, 14h01

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