[Resolvido] Qual a melhor maneira de juntar um array list em uma string?

Pessoal no código abaixo há 2 for’s que fazem a mesma coisa. Qual deles vocês julgam ser melhor e o porquê de sua escolha. Há forma mais eficiente de fazer isso?

[code]
ArrayList lista = new ArrayList<>();

    lista.add(0);
    lista.add(1);
    lista.add(5);
    lista.add(10);

    String juntarLista = "";

    for (Integer integer : lista) {
        if (juntarLista.equals("")) {
            juntarLista += integer;
        } else {
            juntarLista += ", " + integer;
        }
    }

    for (Iterator<Integer> it = lista.iterator(); it.hasNext();) {
        Integer integer = it.next();
        juntarLista += integer;
        if (it.hasNext()) {
            juntarLista += ", ";
        }
    }[/code]

Meu objetivo é fazer uma consulta com a clausula ‘IN’ . Não sei quantos parâmetros virão no arrayList. Estou escrevendo a consulta assim select […] where nome_coluna IN ( ? ); substituindo a ? pela String juntarLista. Há outra forma melhor de fazer isso?

Neste caso é necessário dar prioridade a performance e segurança

Oi tgcmv.

Na verdade, as duas abordagens são equivalentes. Quando você escreve um for nesse estilo (for/each), o que ele faz é usar o iterator na hora da execução, ou seja, exatamente o que o seu segundo código faz!

Além disso, vale lembrar que pra ajudar na performance, a própria JVM troca sua String e as concatenações de String por um StringBuilder. O Paulo Silveira escreveu sobre isso um tempo atrás e vale a pena dar uma lida, caso você não conheça: http://blog.caelum.com.br/revisitando-a-concatenacao-de-strings-stringbuilder-e-stringbuffer/

Como sugestão e dica, tem a classe StringUtils na biblioteca commons-lang. Com ela, você usaria:

String resultado = StringUtils.join(lista, ","); //primeiro parametro a lista e segundo o separador

Só que no fundo, daria na mesma que você encapsular esse código que você fez em uma classe sua para manipular os SQLs ou textos.

PS: Se tiver curiosidade em ver como é implementado o StringUtils.join ;): http://svn.apache.org/viewvc/commons/proper/lang/trunk/src/main/java/org/apache/commons/lang3/StringUtils.java?view=markup linha 3187

[quote=Adriano Almeida]Oi tgcmv.

Na verdade, as duas abordagens são equivalentes. Quando você escreve um for nesse estilo (for/each), o que ele faz é usar o iterator na hora da execução, ou seja, exatamente o que o seu segundo código faz!

Além disso, vale lembrar que pra ajudar na performance, a própria JVM troca sua String e as concatenações de String por um StringBuilder. O Paulo Silveira escreveu sobre isso um tempo atrás e vale a pena dar uma lida, caso você não conheça: http://blog.caelum.com.br/revisitando-a-concatenacao-de-strings-stringbuilder-e-stringbuffer/[/quote]

Muito obrigado. Por isso que gosto do GUJ. Rápido e eficaz :smiley:

Se souber responder também http://www.guj.com.br/java/280370-qual-tem-a-melhor-performance-estatico-ou-dinamico#1477984. :smiley:

O StringBuffer já tinha ouvido falar. sei que tem também o stringBuilder. Vou pesquisar depois qual o melhor dos dois neste caso.

Mais uma vez obrigado pela resposta! :smiley:

[code]String juntarLista = “”;

for (Integer integer : lista) {
if (juntarLista.equals("")) {
juntarLista += integer;
} else {
juntarLista += ", " + integer;
}
}[/code]
a sua condição do if só vai ser verdadeira na primeira vez, então pra que testar em todas?
alternativa:

String juntarLista = lista.get(0); for (Integer integer : lista) { juntarLista += ", " + integer; }
Quanto ao seu segundo código, geralmente utilizamos Iterator explicitamente quando queremos remover ítens da lista enquanto iteramos…
e você também está fazendo o teste desnecessariamente, pois esse if seu só vai ser falso na última iteração, então acaba sendo o mesmo teste desnecessário do primeiro for.
O for declarado desta maneira é parecido com um while (enquanto it.hasNext(), faça…). Seria o mesmo que:

Iterator<Integer> it = lista.iterator(); while (it.hasNext()) { Integer integer = it.next(); ... }
então pra que testar mais uma vez dentro do laço se ele mesmo já faz isso?

[quote=erico_kl]

String juntarLista = lista.get(0); for (Integer integer : lista) { juntarLista += ", " + integer; }
então pra que testar mais uma vez dentro do laço se ele mesmo já faz isso?[/quote]

Desta forma o elemento 0 da lista não iria se repetir 2 vezes?

juntarLista não ficaria equals("<item 0>, <item 0>, <item 1>, <item 2> …")?

[quote=tgcmv][quote=erico_kl]

String juntarLista = lista.get(0); for (Integer integer : lista) { juntarLista += ", " + integer; }
então pra que testar mais uma vez dentro do laço se ele mesmo já faz isso?[/quote]

Desta forma o elemento 0 da lista não iria se repetir 2 vezes?

juntarLista não ficaria equals("<item 0>, <item 0>, <item 1>, <item 2> …")?[/quote]
você está certo, não tinha me tocado disso… nesse caso o for teria que ser trocado por:

for (int i=1; i<lista.size(); i++) { item = lista.get(i); ... }
assim o for começa a contar do segundo ítem da lista…

E como você viu neste link, o uso de StringBuilder poder ser consideravelmente mais eficiente…