Come tagliare un builder di java?

Ho un object StringBuilder che deve essere tagliato (cioè tutti i caratteri spaziali / u0020 e sotto rimossi da entrambe le estremità).

Non riesco a trovare un metodo nel constructor di stringhe che lo farebbe.

  • Dare un doppio valore a Geopoint in sovrapposizioni di GoogleMap
  • Android Clickable TextView Come fare regioni multiple su text e selezione della regione di cattura
  • Come aggiungere l'object all'inizio della list in ArrayAdapter?
  • Sono i widget per Android app (per la home screen) consentiti i gesti?
  • Android con Arduino
  • Invio di cookie con android di http post
  • Ecco cosa sto facendo adesso:

    String trimmedStr = strBuilder.toString().trim(); 

    Questo fornisce esattamente l'output desiderato, ma richiede due stringhe da assegnare anziché uno. C'è un più efficiente per tagliare la string mentre è ancora in StringBuilder?

  • L'installazione di "install" di plugin Gradle Maven non funziona con il progetto della libreria Android
  • consentendo che il GPS non funzioni in modo programmato
  • Android nasconde / apre l'applicazione icona in modo programmato
  • Come restituire un risultato (startActivityForResult) da un'attività TabHost?
  • l'applicazione di thread singolo utilizza multi core in android?
  • Ottenere un errore durante il recupero dei messaggi archiviati (XEP-0313 MAM - chat history) da openfire-4.1.1
  • 6 Solutions collect form web for “Come tagliare un builder di java?”

    Non si dovrebbe usare l'approccio deleteCharAt.

    Come ha sottolineato Boris, il metodo deleteCharAt copia l'arrays in each momento. Il codice in Java 5 che fa questo è simile a questo:

     public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); System.arrayscopy(value, index+1, value, index, count-index-1); count--; return this; } 

    Naturalmente, la speculazione da sola non è sufficiente a scegliere un metodo di ottimizzazione su un altro, quindi ho deciso di mettere a punto i tre approcci in questo thread: l'originale, l'approccio di eliminazione e l'approccio della sottostring.

    Ecco il codice che ho testato per l'orignal:

     public static String trimOriginal(StringBuilder sb) { return sb.toString().trim(); } 

    L'approccio di eliminazione:

     public static String trimDelete(StringBuilder sb) { while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) { sb.deleteCharAt(0); } while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) { sb.deleteCharAt(sb.length() - 1); } return sb.toString(); } 

    E l'approccio della sottostring:

     public static String trimSubstring(StringBuilder sb) { int first, last; for (first=0; first<sb.length(); first++) if (!Character.isWhitespace(sb.charAt(first))) break; for (last=sb.length(); last>first; last--) if (!Character.isWhitespace(sb.charAt(last-1))) break; return sb.substring(first, last); } 

    Ho eseguito 100 test, each volta generando un StringBuffer di milioni di caratteri con dieci mila spazi trapiantati e leader. Il test stesso è molto semplice, ma dà una buona idea di quanto tempo i methods richiedono.

    Ecco il codice al tempo dei tre approcci:

     public static void main(String[] args) { long originalTime = 0; long deleteTime = 0; long substringTime = 0; for (int i=0; i<100; i++) { StringBuilder sb1 = new StringBuilder(); StringBuilder sb2 = new StringBuilder(); StringBuilder sb3 = new StringBuilder(); for (int j=0; j<10000; j++) { sb1.append(" "); sb2.append(" "); sb3.append(" "); } for (int j=0; j<980000; j++) { sb1.append("a"); sb2.append("a"); sb3.append("a"); } for (int j=0; j<10000; j++) { sb1.append(" "); sb2.append(" "); sb3.append(" "); } long timer1 = System.currentTimeMillis(); trimOriginal(sb1); originalTime += System.currentTimeMillis() - timer1; long timer2 = System.currentTimeMillis(); trimDelete(sb2); deleteTime += System.currentTimeMillis() - timer2; long timer3 = System.currentTimeMillis(); trimSubstring(sb3); substringTime += System.currentTimeMillis() - timer3; } System.out.println("original: " + originalTime + " ms"); System.out.println("delete: " + deleteTime + " ms"); System.out.println("substring: " + substringTime + " ms"); } 

    Ho ottenuto la seguente output:

     original: 176 ms delete: 179242 ms substring: 154 ms 

    Come si vede, l'approccio a sottostring fornisce un'ottimizzazione molto leggera rispetto all'originale "due stringhe". Tuttavia, l'approccio di eliminazione è estremamente lento e dovrebbe essere evitato.

    Quindi per rispondere alla tua domanda: stai bene tagliando il tuo StringBuilder come hai suggerito nella domanda. La leggerissima ottimizzazione che il metodo di sottostring offre probabilmente non giustifica il codice in eccesso.

    Non preoccuparti di avere due corde. È una microoptimizzazione.

    Se hai veramente rilevato un collo di bottiglia, puoi avere un ritaglio quasi costante, basta semplicemente ripetere i primi N caratteri finché non sono Character.isWhitespace(c)

    Ho utilizzato l'approccio di analisi di Zaven e il metodo di eliminazione (start, end) di StringBuilder che esegue molto meglio dell'approccio deleteCharAt (index) , ma leggermente peggiore dell'approccio di substring () . Questo metodo utilizza anche la copia dell'arrays, ma la copia dell'arrays è chiamata molto less volte (solo due volte nel caso peggiore). Inoltre, questo evita la creazione di più istanze di stringhe intermedie in caso di trim () chiamato ripetutamente nello stesso object StringBuilder.

     public class Main { public static String trimOriginal(StringBuilder sb) { return sb.toString().trim(); } public static String trimDeleteRange(StringBuilder sb) { int first, last; for (first = 0; first < sb.length(); first++) if (!Character.isWhitespace(sb.charAt(first))) break; for (last = sb.length(); last > first; last--) if (!Character.isWhitespace(sb.charAt(last - 1))) break; if (first == last) { sb.delete(0, sb.length()); } else { if (last < sb.length()) { sb.delete(last, sb.length()); } if (first > 0) { sb.delete(0, first); } } return sb.toString(); } public static String trimSubstring(StringBuilder sb) { int first, last; for (first = 0; first < sb.length(); first++) if (!Character.isWhitespace(sb.charAt(first))) break; for (last = sb.length(); last > first; last--) if (!Character.isWhitespace(sb.charAt(last - 1))) break; return sb.substring(first, last); } public static void main(String[] args) { runAnalysis(1000); runAnalysis(10000); runAnalysis(100000); runAnalysis(200000); runAnalysis(500000); runAnalysis(1000000); } private static void runAnalysis(int stringLength) { System.out.println("Main:runAnalysis(string-length=" + stringLength + ")"); long originalTime = 0; long deleteTime = 0; long substringTime = 0; for (int i = 0; i < 200; i++) { StringBuilder temp = new StringBuilder(); char[] options = {' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd'}; for (int j = 0; j < stringLength; j++) { temp.append(options[(int) ((Math.random() * 1000)) % options.length]); } String testStr = temp.toString(); StringBuilder sb1 = new StringBuilder(testStr); StringBuilder sb2 = new StringBuilder(testStr); StringBuilder sb3 = new StringBuilder(testStr); long timer1 = System.currentTimeMillis(); trimOriginal(sb1); originalTime += System.currentTimeMillis() - timer1; long timer2 = System.currentTimeMillis(); trimDeleteRange(sb2); deleteTime += System.currentTimeMillis() - timer2; long timer3 = System.currentTimeMillis(); trimSubstring(sb3); substringTime += System.currentTimeMillis() - timer3; } System.out.println(" original: " + originalTime + " ms"); System.out.println(" delete-range: " + deleteTime + " ms"); System.out.println(" substring: " + substringTime + " ms"); } } 

    Produzione:

     Main:runAnalysis(string-length=1000) original: 0 ms delete-range: 4 ms substring: 0 ms Main:runAnalysis(string-length=10000) original: 4 ms delete-range: 9 ms substring: 4 ms Main:runAnalysis(string-length=100000) original: 22 ms delete-range: 33 ms substring: 43 ms Main:runAnalysis(string-length=200000) original: 57 ms delete-range: 93 ms substring: 110 ms Main:runAnalysis(string-length=500000) original: 266 ms delete-range: 220 ms substring: 191 ms Main:runAnalysis(string-length=1000000) original: 479 ms delete-range: 467 ms substring: 426 ms 

    solo uno di voi ha preso in considerazione che quando si convertono il constructor di stringhe in una "string" e quindi "trim" che si crea un object immutabile due volte che deve essere raccolto spazzatura, così l'allocazione totale è:

    1. Oggetto Stringbuilder
    2. string immutabile dell'object immutabile dell'object SB della string che è stata tagliata.

    Quindi, mentre può "apparire" che il trim è più veloce, nel mondo reale e con uno schema di memory caricato sarà infatti peggiore.

    Ottieni due stringhe, ma mi aspettavo che i dati vengano assegnati solo una volta. Poiché le stringhe in Java sono immutabili, mi aspetto che l'implementazione trim ti dà un object che condivide gli stessi dati di carattere, ma con diversi indici di avvio e di fine. Alless questo è quello che fa il metodo substr. Quindi, tutto ciò che cercherai di ottimizzare questo avrà certamente l'effetto opposto, dal momento che aggiungi un sovraccarico che non è necessario.

    Basta passare attraverso il metodo trim () con il debugger.

    Ho fatto qualche codice. Funziona e i casi di prova sono lì per voi da vedere. Fammi sapere se questo va bene.

    Codice principale –

     public static StringBuilder trimStringBuilderSpaces(StringBuilder sb) { int len = sb.length(); if (len > 0) { int start = 0; int end = 1; char space = ' '; int i = 0; // Remove spaces at start for (i = 0; i < len; i++) { if (sb.charAt(i) != space) { break; } } end = i; //System.out.println("s = " + start + ", e = " + end); sb.delete(start, end); // Remove the ending spaces len = sb.length(); if (len > 1) { for (i = len - 1; i > 0; i--) { if (sb.charAt(i) != space) { i = i + 1; break; } } start = i; end = len;// or len + any positive number ! //System.out.println("s = " + start + ", e = " + end); sb.delete(start, end); } } return sb; } 

    Il codice completo con il test –

     package source; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; public class StringBuilderTrim { public static void main(String[] args) { testCode(); } public static void testCode() { StringBuilder s1 = new StringBuilder(""); StringBuilder s2 = new StringBuilder(" "); StringBuilder s3 = new StringBuilder(" "); StringBuilder s4 = new StringBuilder(" 123"); StringBuilder s5 = new StringBuilder(" 123"); StringBuilder s6 = new StringBuilder("1"); StringBuilder s7 = new StringBuilder("123 "); StringBuilder s8 = new StringBuilder("123 "); StringBuilder s9 = new StringBuilder(" 123 "); StringBuilder s10 = new StringBuilder(" 123 "); /* * Using a rough form of TDD here. Initially, one one test input * "test case" was added and rest were commented. Write no code for the * method being tested. So, the test will fail. Write just enough code * to make it pass. Then, enable the next test. Repeat !!! */ ArrayList<StringBuilder> ins = new ArrayList<StringBuilder>(); ins.add(s1); ins.add(s2); ins.add(s3); ins.add(s4); ins.add(s5); ins.add(s6); ins.add(s7); ins.add(s8); ins.add(s9); ins.add(s10); // Run test for (StringBuilder sb : ins) { System.out .println("\n\n---------------------------------------------"); String expected = sb.toString().trim(); String result = trimStringBuilderSpaces(sb).toString(); System.out.println("In [" + sb + "]" + ", Expected [" + expected + "]" + ", Out [" + result + "]"); if (result.equals(expected)) { System.out.println("Success!"); } else { System.out.println("FAILED!"); } System.out.println("---------------------------------------------"); } } public static StringBuilder trimStringBuilderSpaces(StringBuilder inputSb) { StringBuilder sb = new StringBuilder(inputSb); int len = sb.length(); if (len > 0) { try { int start = 0; int end = 1; char space = ' '; int i = 0; // Remove spaces at start for (i = 0; i < len; i++) { if (sb.charAt(i) != space) { break; } } end = i; //System.out.println("s = " + start + ", e = " + end); sb.delete(start, end); // Remove the ending spaces len = sb.length(); if (len > 1) { for (i = len - 1; i > 0; i--) { if (sb.charAt(i) != space) { i = i + 1; break; } } start = i; end = len;// or len + any positive number ! //System.out.println("s = " + start + ", e = " + end); sb.delete(start, end); } } catch (Exception ex) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); ex.printStackTrace(pw); sw.toString(); // stack trace as a string sb = new StringBuilder("\nNo Out due to error:\n" + "\n" + sw); return sb; } } return sb; } } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.