StringBuilder, apostila FJ11 da Caelum [RESOLVIDO]

4 respostas
java
E

Alguém pode ajudar com esses códigos. O exercício(está postado abaixo da minha pergunta) pede basicamente para fazer um algoritmo que inverta uma frase, utilizando String e depois modificando-o para StringBuilder. Mas quero saber se a alteração que eu fiz está correta e também um esclarecimento sobre o lance do objeto na memória, pela questão da String ser imutável e a StringBuilder não. Pois com a alteração que eu fiz, parece que não estou aproveitando a mutabilidade da Builder, mas foi a unica forma que consegui fazer.

PS: A linha que eu marquei como dúvida no código é pelo fato de parecer estar criando objetos String na memória igual o código primeiro código.

14)Dada uma frase, reescreva essa frase com as palavras na ordem invertida. "Socorram-me, subi no ônibus em Marrocos” deve retornar "Marrocos em ônibus no subi Socorram-me,” . Utilize o método split da String para te auxiliar.

  1. Como você poderia reescrever o método de escrever a String de trás para a frente usando um StringBuilder ?
public void invertOrder(String frase) {
                long temp = System.nanoTime();
                String[] palavras = frase.split(" "); 

                for (int i = palavras.length - 1; i >= 0; i--) {
                    System.out.print(palavras[i]);
                    System.out.print(" ");
                }
                // tempo de execução 
                System.out.println(System.nanoTime() - temp);
            }

// Reescrito com StringBuilder
            public void invertBuilder(String frase) {
                long temp = System.nanoTime();                   
                StringBuilder palavras = new StringBuilder(); 

                // A Dúvida está na linha abaixo.
                for (String palavra : frase.split(" ")) {
                    palavras.insert(0, palavra + " ");
                }
                System.out.println(palavras);

               // tempo de execução 
                System.out.println(System.nanoTime() - temp);
            }

Tentei ser o mais claro possível, desculpe se não organizei muito bem as minhas dúvidas com o código.

4 Respostas

D

Se estiver funcionando, então está correto. Sobre o lance da memória, o StringBuilder só será melhor se a String for grande. Ambos usam um array de caracteres para armazenar na memória, a principal diferença é q podemos definir um tamanho inicial no StringBuilder, assim evita a reconstrução desnecessária do texto sempre q estoura o array ou wuando há alguma alteração nela.

// define um tamanho inicial (4/3 da frase, uso geralmente 1/3 a mais do texto original)
StringBuilder palavrasBuilder = new StringBuilder(frase.length() + frase.length() / 3);
// formato String
String palavrasString = "";

String[] palavrasArray = frase.split(" "); 

// mesmo loop do inverter ordem
for (int i = palavrasArray.length - 1; i >= 0; i--) {
    // usar append é melhor
    palavrasBuilder.append(palavrasArray[i]).append(' ');
    palavrasString += palavrasArray[i] + ' ';
}

System.out.println("Builder: " + palavrasBuilder.toString());
System.out.println("String: " + palavrasString);

Sobre a duvida no código, sim está criando novo objeto pois está usando o +, use o append, o insert desloca os caracteres, no primeiro código só está sendo criado no System.out.print(" ");

E

Substitui o ‘+’ com outro insert, acho que isso funciona para não criar outra String na memória não é mesmo?

palavras.insert(0, palavra).insert(0, ' ');

Eu fiz com insert porque a frase já vai ficando invertida, justamente por causa do deslocamento, pois como eu usei ‘for each’, não tenho índice para controlar a posição usando ‘append’. Agora como você recomendou, em relação ao desempenho, tem alguma diferença entre usar o ‘append’ ou ‘insert’?

D

Sim, o append adiciona a string no final, o insert move para alocar a nova string e depois insere, quanto maior a quantidade de caracteres para ser movido, mais lento fica o insert, portanto o append é mais rápido.

Não sei se seria possível usar o foreach com append.

Vc inverteu, para ter o mesmo efeito seria:
palavras.insert(0, ' ').insert(0, palavra);

Acho que fazendo palavras.insert(0, palavra + ' ') teria melhor desempenho, pois diminui a quantidade de vezes q que o builder precisa deslocar os caracteres para adicionar a palavra.

Não sei se vc sabe, mas a classe String tem como atributo uma cadeia de caracteres (char[]) assim como a StringBuilder.

E

Acho que está mais claro agora.
Sim, notei que havia invertido mesmo, e sobre a cadeia de caracteres,eu também sabia, mas obrigado pela observação.

Criado 15 de abril de 2016
Ultima resposta 15 de abr. de 2016
Respostas 4
Participantes 2