giovedì 24 settembre 2015

Java - rimozione degli spazi e altri caratteri

Come rimuovere gli spazi da una stringa

ma anche altri caratteri

17 Ottobre 2015: l'articolo e' stato aggiornato a seguito di una segnalazione
Primo Modo (non ottimizzato):
diciamo questo serve piu' per esercizio che di reale utilita'
sostanzialmente si crea un array di char (usando il metodo toCharArray) e si "scorre" tutto l'array... se il carattere non e' uno spazio si aggiunge alla stringa che verra' restituita, se lo e' ovviamente no.
Va da se che questo metodo e' altamente dispendioso in termini di risorse in quanto bisogna percorrere tutta la stringa (pensate ad un testo molto lungo invece che ad una singola parola). Quindi vale come esercizio accademico ma non ne consiglio l'utilizzo.

Secondo Modo (ottimizzato):
si usa il metodo split, passandogli lo spazio come parametro (Unicode: \u0020) poi si prendono i vari tronconi (chunks) e si "ri-appiccicano" insieme nella stringa da restituire. Va da se' che non dovendo scansionare tutta la stringa questo metodo e' molto piu' efficiente - addendum: del primo.

Per rimuovere qualsiasi altro carattere (o stringa) 

1) farselo passare come parametro 

2) sostituirlo dove nei metodi sopra c'e' lo spazio

In alternativa:
Usare il metodo replace passando come primo parametro la stringa (o il carattere) da levare e come secondo una stringa vuota ("")


In realta' prendendo una tabella comparativa da questo post di stackoverflow si vede che lo split e' uno dei metodi peggiori per cui su grandi volumi di file e' molto piu' efficace la classe Scanner

Tokenizer String.split() while+SubString Scanner ScannerWithCompiledPattern
4.0 ms 5.1 ms 1.2 ms 0.5 ms 0.1 ms
4.4 ms 4.8 ms 1.1 ms 0.1 ms 0.1 ms
3.5 ms 4.7 ms 1.2 ms 0.1 ms 0.1 ms
3.5 ms 4.7 ms 1.1 ms 0.1 ms 0.1 ms
3.5 ms 4.7 ms 1.1 ms 0.1 ms 0.1 ms

10 commenti:

  1. Due pIccole note: lo split al suo interno "scorre" comunque tutta la stringa, in più fa altri controlli che peggiorano le cose invece di ottimizzare.
    In Java è sempre sconsigliato concatenare le stringhe ma si usano gli StringBuffer o StringBuilder.

    RispondiElimina
  2. ti cito un articolo di stackoverflow secondo il quale s1 + s2 etc
    dove s sono stringhe equivale dietro le quinte a StringBuilder(s1).append(s2).toString();

    RispondiElimina
    Risposte
    1. "Dietro le quinte" vuol dire che fa una trasformazione in più che si può evitare (è lei che ha detto che il metodo è ottimizzato). Seguendo il link che ha riportato ho trovato questo esempio abbastanza esplicativo:

      public class Main
      {
      public static void main(String[] args)
      {
      long now = System.currentTimeMillis();
      slow();
      System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");

      now = System.currentTimeMillis();
      fast();
      System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
      }

      private static void fast()
      {
      StringBuilder s = new StringBuilder();
      for(int i=0;i<100000;i++)
      s.append("*");
      }

      private static void slow()
      {
      String s = "";
      for(int i=0;i<100000;i++)
      s+="*";
      }
      }

      Elimina
    2. allora innanzitutto per la netiquette l'uso del lei e' considerato inappropriato.
      In secundis, a seguito del tuo commento ho aggiornato l'articolo perche' non si capiva. L'ottimizzazione non e' assoluta ma relativa al metodo precedente - da quel che commenti noto che non hai notato ne' la seconda mia risposta ne' l'aggiornamento del post...

      Elimina
  3. per lo split: qui c'e' una tabella comparativa - effettivamente non ha performance esaltanti - via giu' mi tocchera' aggiornare il post...

    RispondiElimina
  4. @Antoniuccio
    per curiosita' sono andato a rivedere il link che ho postato relativo allo string builder ma non ho assolutamente trovato quella pappardella sul main che tu citi.. Saresti cosi' gentile da dirmi dove l'hai trovata?

    RispondiElimina
    Risposte
    1. Sul tuo link ("tuo", sono stato bravo?) dicono in un commento "There an excellent topic here explaining why you should use the + operator."
      Per "here" si intende http://stackoverflow.com/questions/1532461/stringbuilder-vs-string-concatenation-in-tostring-in-java

      Elimina
    2. @Antoniuccio
      "tuo", sono stato bravo?
      si
      "There an excellent topic here explaining why you should use the + operator."
      che dice sostanzialmente quello che avevo detto io sulla concatenazione delle stringhe. il + equivale ad uno string builder

      per quel che riguarda i link puoi usare il tag "anchor" (a href ="indirizzo del link" e dentro il tag il testo che vuoi visualizzare) - qui la spiegazione del w3 school

      Elimina
    3. "Il + equivale ad uno string builder" ma non in termini di tempo (aggiungerei anche di spazio). Hai provato ad eseguire la pappardella?
      PS ti ringrazio per la spiegazione del tag -.-

      Elimina
  5. @Antoniuccio
    Il + equivale ad uno string builder" ma non in termini di tempo (aggiungerei anche di spazio)
    bisognerebbe fare un benchmark comparativo (o trovarlo) - se non hai furia l'aggiungo alla todo-list
    Hai provato ad eseguire la pappardella?
    mancano i metodi fast and slow che non si sa esattamente cosa facciano...comunque vedi sopra :)
    ti ringrazio per la spiegazione del tag -.-
    ...figurati... e' molto piu' comodo cliccare su un link che non fare cut'n'paste - anche se alcuni browser come opera (e mi sa anche feriefox ma quest'ultimo non come shortcut) supportano l'incolla e vai

    RispondiElimina

I messaggi non appaiono subito ma a seguito dell'approvazione di un moderatore. Siete pregati di seguire le seguenti regole