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 :

Insertion de retours à la ligne dans un String


Sujet :

Langage Java

  1. #1
    Membre averti Avatar de BakaOnigiri
    Inscrit en
    Avril 2002
    Messages
    366
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 366
    Points : 437
    Points
    437
    Par défaut Insertion de retours à la ligne dans un String
    Bien le bonjour,

    j'ai une chaine de caractère, et je voudrais insérer dedans : X retours à la ligne.

    En fait j'ai une ligne : "....................................................................."

    Je doit insérer des retour à la ligne toute les X colonnes, pour former Y lignes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
     0                     X
    "......................."  0
    "......................."
    "......................."  Y
    je suis partie dans l'idée de faire des bouts de string (dans un tableau de string) puis de reconcaténer le tout dans une string finale, mais c'est pas terrible, surtout s'il y a plus facile et plus rapide.


    Merci.

  2. #2
    Membre régulier Avatar de TrYde
    Homme Profil pro
    Responsable de l'industrialisation logiciel
    Inscrit en
    Juillet 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de l'industrialisation logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 55
    Points : 80
    Points
    80
    Par défaut
    Bonjour,

    Sans passer par une table de Strings, pour insérer simplement des retours à la ligne, une chaîne temporaire et une boucle feront l'affaire.

    Genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    // Nombre de colonnes = x
    // Chaîne d'entrée = strSource
     
    String strResultat = "";
    for (int i = 0; i < strSource.length(); i += x) {
        strResultat = strResultat + strSource.substring(i, i + x - 1) + '\n';
    }
     
    // Ensuite on ajoute la dernière ligne si incomplète
    if (strSource.length % x != 0) {
        strResultat = strResultat + strSource.substring(strSource.length() - strSource.length() % x);
    }

  3. #3
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    et remplacer les \n par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.getPropert('path.separator');
    histoire d'être bien portable

  4. #4
    Membre chevronné
    Avatar de Deadpool
    Homme Profil pro
    Inscrit en
    Novembre 2005
    Messages
    1 312
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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
    Citation Envoyé par sinok Voir le message
    et remplacer les \n par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.getPropert('path.separator');
    histoire d'être bien portable
    Heu tu voulais sans doute plutôt dire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.getProperty("line.separator");

  5. #5
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    oups, gouré de property, merci de la correction

  6. #6
    Membre averti Avatar de BakaOnigiri
    Inscrit en
    Avril 2002
    Messages
    366
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 366
    Points : 437
    Points
    437
    Par défaut
    Merci beaucoup TrYde, sauf qu'il faut modifier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strSource.substring(i, i + x - 1)
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    strSource.substring(i, i + x)
    en effet, le '-1' fait qu'on détruit un caractère, alors qu'en fait c'est bien une insertion que je cherchais, mais merci beaucoup.

    De plus j'ai mis en commentaire, le 'if' qui suit, parceque ma chaine est normalement toujours de la bonne taille, mais on ne sais jamais.

    Merci sinok et Deadpool en effet c'est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    System.getProperty("line.separator");
    qu'il faut utiliser

  7. #7
    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,


    Attention il est préférable d'utiliser un StringBuffer/StringBuilder plutôt que de faire des concaténations de String dans une boucle !


    a++

  8. #8
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 311
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Salut,


    Attention il est préférable d'utiliser un StringBuffer/StringBuilder plutôt que de faire des concaténations de String dans une boucle !


    a++
    C'est une histoire de performance ???

  9. #9
    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 DevTeam_ Voir le message
    C'est une histoire de performance ???
    Oui.

    A chaque itération de la boucle tu auras 2 nouveaux objets (au moins de la taille de la chaine) et 2 objets seront "détruits".

    Au final cela peut revenir à allouer une énorme quantité de mémoire, même si la chaine finale est plutôt modeste...


    Plus d'info : Comment concatener des chaînes de caractères ?


    a++


    [edit] Et je dirais même plus : ce n'est pas un problème de performance mais bien une erreur de codage !!!

  10. #10
    Membre régulier Avatar de TrYde
    Homme Profil pro
    Responsable de l'industrialisation logiciel
    Inscrit en
    Juillet 2005
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Responsable de l'industrialisation logiciel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2005
    Messages : 55
    Points : 80
    Points
    80
    Par défaut
    Je plussoie tout ça, j'ai posté mon premier exemple un peu à la va vite
    Enfin c'était surtout pour l'idée...

  11. #11
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 311
    Points : 318
    Points
    318
    Par défaut
    Ok, merci pour l'explication!

    Par contre, "erreur de codage" me semble exagéré puisque la concaténation de chaine via "+=" n'entraine pas de résultat final différent...

  12. #12
    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 DevTeam_ Voir le message
    Par contre, "erreur de codage" me semble exagéré puisque la concaténation de chaine via "+=" n'entraine pas de résultat final différent...
    Je prend un exemple tout con : générer une String de 100000 char à partir de ligne de 26 char (les lettres de l'alphabet).

    • Avec un StringBuffer c'est quasiment instantané (la différence avec currentTimeMillis() me donne ~16ms).
    • Avec une concaténation cela me prend plus de 2 secondes...



    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
    public class Main {
     
     
    	public static String create1(String line, int count) {
    		StringBuffer buffer = new StringBuffer(); 
    		for (int i=0; i<count; i++) {
    			buffer.append(line);
    		}
    		return buffer.toString();
    	}
     
    	public static String create2(String line, int count) {
    		String buffer = ""; 
    		for (int i=0; i<count; i++) {
    			buffer += line;
    		}
    		return buffer;
    	}
     
     
     
    	public static void main(String[] args) throws SAXException, InstantiationException, IllegalAccessException {
     
    		String line = "abcdefghijklmnopqrstuvwxyz\n"; //26 char + 1 (\n)
    		int count = 3800; // 3800 lignes de 27 caractères => ~ 100K
    		long start, stop;
     
    		System.out.print("Avec StringBuffer :  ");
    		start = System.currentTimeMillis();
    		String str1 = create1(line, count);
    		stop = System.currentTimeMillis();
    		System.out.println( (stop-start) + " ms" );
     
    		System.out.print("Avec String +     :  ");
    		start = System.currentTimeMillis();
    		String str2 = create2(line, count);
    		stop = System.currentTimeMillis();
    		System.out.println( (stop-start) + " ms" );
     
        }
     
    }

    De plus la concaténation utilise un grand nombre d'objet temporaire et donc beaucoup de mémoire : a chaque itération on crée un nouvelle objet de la taille du buffer + la ligne ajouté (près de 200 Mo seront alloué/désalloué dans ce cas précis). Si tu lances le programme ci-dessus avec l'option -verbose:gc tu verras que le garbage collector fera un très grand nombre de passage dans le second cas


    Et comme un bout de code est souvent plus explicite, la boucle suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i=0; i<count; i++) {
    	buffer += line;
    }
    Est en fait compilé de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (int i=0; i<count; i++) {
    	buffer = new StringBuffer().append(buffer).append(line).toString();
    }

    Pour moi c'est bien une erreur : il ne faut pas utiliser l'opérateur + dans une boucle !


    a++

  13. #13
    Membre averti Avatar de BakaOnigiri
    Inscrit en
    Avril 2002
    Messages
    366
    Détails du profil
    Informations forums :
    Inscription : Avril 2002
    Messages : 366
    Points : 437
    Points
    437
    Par défaut
    Bien, j'ai donc adapté :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // mise en forme de la chaine de caractère
            StringBuffer strResultat = new StringBuffer();
            for (int i = 0; i < paffNbCol * paffNbRow; i += paffNbCol)
            {
                strResultat.append(paffTextInfo.substring(i, i + paffNbCol) + System.getProperty("line.separator"));
            }
     
            // Ensuite on ajoute la dernière ligne si incomplète
            if (paffTextInfo.length() % paffNbCol != 0)
            {
                strResultat.append(paffTextInfo.substring(paffTextInfo.length() - paffTextInfo.length() % paffNbCol));
            }
     
            setInfoText(strResultat.toString());
    C'est bien comme çà qu'il faut utiliser les StringBuffer ?

  14. #14
    Expert éminent sénior
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Points : 12 977
    Points
    12 977
    Par défaut
    Mouaip

  15. #15
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 311
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Je prend un exemple tout con : générer une String de 100000 char à partir de ligne de 26 char (les lettres de l'alphabet).

    • Avec un StringBuffer c'est quasiment instantané (la différence avec currentTimeMillis() me donne ~16ms).
    • Avec une concaténation cela me prend plus de 2 secondes...
    C'est clair... Par contre, en testant je tourne plus aux alentours de 10 secondes que 2 pour la concaténation

  16. #16
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 311
    Points : 318
    Points
    318
    Par défaut
    Au temps pour moi, j'avais mal sizé ma JVM (ce qui appuie encore la démonstration !)

  17. #17
    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 BakaOnigiri Voir le message
    C'est bien comme çà qu'il faut utiliser les StringBuffer ?
    Oui tout à fait !

    A la rigueur il y a une toute petite optimisation si tu connais la taille finale de la chaine, c'est de spécifier cette taille au constructeur de StringBuffer afin d'éviter le redimensionnement automatique.

    Mais c'est assez bien géré donc la différence ne sera pas vraiment évidente (inutile de s'embêter à calculer la taille si on ne l'a pas facilement).

    A noter qu'avec Java 5 on peut utiliser StringBuilder à la place (même chose mais non synchronisé et donc potentiellement plus véloce), même si encore une fois la différence n'est pas si évidente...

    Citation Envoyé par DevTeam_ Voir le message
    C'est clair... Par contre, en testant je tourne plus aux alentours de 10 secondes que 2 pour la concaténation
    Après cela dépend de ta machine et de la JVM, car le garbage collector est très sollicité. Je viens de tester avec une JVM 5.0 et cela me prend près de 6 secondes (le premier test était effectué sur une JVM 6).


    a++

  18. #18
    Membre averti
    Inscrit en
    Octobre 2007
    Messages
    311
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 311
    Points : 318
    Points
    318
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Oui tout à fait !
    Après cela dépend de ta machine et de la JVM, car le garbage collector est très sollicité. Je viens de tester avec une JVM 5.0 et cela me prend près de 6 secondes (le premier test était effectué sur une JVM 6).

    a++
    Yep, j'ai sizé la JVM à 64M mini et je suis tombé à 1sec et des poussières. JVM 5

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

Discussions similaires

  1. Insertion retour à la ligne dans champ mémo
    Par PapouDomi dans le forum VBA Access
    Réponses: 2
    Dernier message: 10/03/2011, 09h06
  2. Retour a la ligne dans un string
    Par naazih dans le forum Débuter
    Réponses: 11
    Dernier message: 09/06/2008, 11h37
  3. [débutant] Gestion retour à la ligne d'une String dans une JSP
    Par caballero dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 26/02/2008, 12h14
  4. Insertion d'un retour à la ligne dans une TextBox
    Par clodius46 dans le forum VBA Word
    Réponses: 2
    Dernier message: 05/09/2007, 23h24
  5. [VB.NET] Enlever les retours à la ligne dans une string
    Par adrix26 dans le forum Windows Forms
    Réponses: 6
    Dernier message: 09/01/2007, 23h27

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