Eu tenho um ArrayList
que eu quero produzir completamente como uma String. Essencialmente, quero exibi-lo em ordem, usando o toString
de cada elemento separado por tabulações. Existe alguma maneira rápida de fazer isso? Você pode fazer um loop através dele (ou remover cada elemento) e concatená-lo em uma String, mas acho que isso será muito lento.
353
Respostas:
Basicamente, o uso de um loop para iterar sobre a
ArrayList
é a única opção:NÃO use esse código, continue lendo na parte inferior desta resposta para ver por que não é desejável e qual código deve ser usado:
De fato, uma concatenação de strings será ótima, pois o
javac
compilador otimizará a concatenação de strings como uma série deappend
operaçõesStringBuilder
. Aqui está uma parte da desmontagem do bytecode dofor
loop do programa acima:Como pode ser visto, o compilador otimiza esse loop usando a
StringBuilder
, portanto, o desempenho não deve ser uma grande preocupação.(OK, à segunda vista, ele
StringBuilder
está sendo instanciado em cada iteração do loop, portanto, pode não ser o bytecode mais eficiente. Instanciar e usar um explícitoStringBuilder
provavelmente produziriam melhor desempenho.)Na verdade, acho que ter qualquer tipo de saída (seja em disco ou na tela) será pelo menos uma ordem de magnitude mais lenta do que ter que se preocupar com o desempenho de concatenações de strings.
Edit: Como apontado nos comentários, a otimização do compilador acima está de fato criando uma nova instância
StringBuilder
em cada iteração. (O que observei anteriormente.)A técnica mais otimizada a ser usada será a resposta de Paul Tomblin , pois apenas instancia um único
StringBuilder
objeto fora dofor
loop.Reescrevendo o código acima para:
Instanciará apenas
StringBuilder
uma vez fora do loop e fará apenas as duas chamadas para oappend
método dentro do loop, conforme evidenciado neste bytecode (que mostra a instanciaçãoStringBuilder
e o loop):Portanto, a otimização manual deve ter um desempenho melhor, pois o interior do
for
loop é mais curto e não é necessário instanciar umStringBuilder
em cada iteração.fonte
Java
ou Geewax paraAndroid
No Java 8 ou posterior:
Caso
list
não seja do tipo String, um coletor de junção pode ser usado:fonte
Se você estiver fazendo isso no Android, existe um bom utilitário para isso chamado TextUtils, que possui um
.join(String delimiter, Iterable)
método.Obviamente, não uso muito fora do Android, mas achei que eu o adicionaria a este tópico ...
fonte
TextUtils.join
leva umObject[]
, eu suponho que ele esteja chamandotoString()
cada token. Será quePatientDetails
implementartoString()
? Se isso não resolver o problema, você pode ficar preso fazendo algo com aSeparator
classe.org.apache.lang3.StringUtils
não faz praticamente o mesmo, assim que sua resposta era absolutamente de muita utilidade para mim fora do Android :)Faça o download do Apache Commons Lang e use o método
Você pode implementá-lo sozinho, é claro, mas o código deles é totalmente testado e provavelmente é a melhor implementação possível.
Sou um grande fã da biblioteca Apache Commons e também acho que é um ótimo complemento para a Java Standard Library.
fonte
StringUtils.join(list.toArray(),"\t")
Essa é uma pergunta bastante antiga, mas acho que devo adicionar uma resposta mais moderna - use a
Joiner
classe do Guava :fonte
Mudar a lista para uma string legível e significativa é realmente uma pergunta comum que todos podem encontrar.
Caso 1 . Se você tiver o StringUtils do apache no caminho da sua classe (como no rogerdpack e Ravi Wallau):
Caso 2 . Se você deseja usar apenas maneiras do JDK (7):
Apenas nunca construa rodas sozinho, não use loop para esta tarefa de uma linha.
fonte
Arrays.toString(myList.toArray())
- a solução mais fácil e diretaArrays.toString(list.toArray())
é fácil de escrever, mas altamente ineficiente.Se você estava procurando uma linha única rápida, a partir do Java 5, você pode fazer isso:
Além disso, se seu objetivo é apenas imprimir o conteúdo e estiver menos preocupado com o "\ t", você pode simplesmente fazer o seguinte:
que retorna uma string como
Se você tiver um Array (não ArrayList), poderá fazer o mesmo assim:
fonte
m
domicílios nasn
cidades dosx
estados, você diria que éO(mnx)
ouO(n^3)
, mas posso reformulá-lo para dizer "procure essa pessoa neste país" e você imediatamente me diráO(n)
. Além disso, todos os algoritmos aqui são geralmenteO(n)
, não há loop dentro de um loop.Faça um loop e chame toString. Não existe uma maneira mágica, e se houvesse, o que você acha que estaria fazendo debaixo das cobertas, a não ser percorrê-la? A única micro-otimização seria usar o StringBuilder em vez do String, e mesmo isso não é uma grande vitória - concatenar seqüências se transforma em StringBuilder sob as cobertas, mas pelo menos se você escrever dessa maneira, poderá ver o que está acontecendo.
fonte
A maioria dos projetos Java geralmente tem o apache-commons lang disponível. O método StringUtils.join () é muito bom e possui vários sabores para atender quase todas as necessidades.
fonte
join(...)
método possui variantes para matrizes e coleções.O Android tem uma classe TextUtil que você pode usar http://developer.android.com/reference/android/text/TextUtils.html
fonte
Para este caso de uso simples, você pode simplesmente juntar as cadeias com vírgula. Se você usa o Java 8:
caso contrário, commons-lang possui um método join ():
fonte
Uma maneira elegante de lidar com caracteres de separação à direita é usar o Class Separator
O método toString do Class Separator retorna o separador, exceto a primeira chamada. Assim, imprimimos a lista sem arrastar (ou, neste caso) separadores à esquerda.
fonte
No Java 8 é simples. Veja o exemplo da lista de números inteiros:
Ou versão multilinha (que é mais simples de ler):
Atualização - uma versão mais curta
fonte
filter
. No final, é muito mais fácil ler o código.String
bom. Se a sua lista de um deInteger
s você tem um problemaÉ um
O(n)
algoritmo de qualquer maneira (a menos que você tenha criado uma solução multithread em que você dividiu a lista em várias sublistas, mas acho que não é isso que você está pedindo).Basta usar um
StringBuilder
como abaixo:o
StringBuilder
será muito mais rápido que concatenação porque você não será re-instanciar umString
objeto em cada concatenação.fonte
Caso você esteja no Android e ainda não esteja usando o Jack (por exemplo, porque ainda falta suporte para a Execução Instantânea) e se desejar ter mais controle sobre a formatação da sequência resultante (por exemplo, gostaria de usar o caractere de nova linha como o divisor de elementos) e por acaso usar / desejar usar a biblioteca StreamSupport (para usar fluxos no Java 7 ou versões anteriores do compilador), você poderia usar algo assim (eu coloquei esse método na minha classe ListUtils):
E, é claro, certifique-se de implementar toString () na classe dos objetos da lista.
fonte
reduce
é extremamente ineficiente para a concatenação de String. Você deve fazer isso da maneira Java 8return StreamSupport.stream(list).map(Object::toString).collect(joining("\n"))
que utiliza internamenteStringJoiner
. Não há razão para que você também não possa fazer isso com o streamsupport .Optional#get
) se ele receber uma lista vazia.Se você não quiser o último \ t após o último elemento, precisará usar o índice para verificar, mas lembre-se de que isso apenas "funciona" (ou seja, é O (n)) quando a lista implementa o RandomAccess.
fonte
O código abaixo pode ajudá-lo,
Resultado:
fonte
Pode não ser o melhor caminho, mas o caminho elegante.
Arrays.deepToString (Arrays.asList ("Teste", "Teste2")
Resultado
[Teste, Teste2]
fonte
Seria bom o seguinte:
fonte
Se você estiver usando o Eclipse Collections , poderá usar o
makeString()
métodoSe você pode converter seu
ArrayList
em umFastList
, pode se livrar do adaptador.Nota: Sou um colaborador das Coleções Eclipse.
fonte
Você passa para a
new StringJoiner
sequência char que você deseja que seja usada como separador. Se você deseja fazer um CSV:new StringJoiner(", ");
fonte
Em uma linha: de [12,0,1,78,12] a 12 0 1 78 12
fonte
Para separar usando guias em vez de usar println, você pode usar print
fonte
Eu vejo alguns exemplos que dependem de recursos adicionais, mas parece que essa seria a solução mais simples: (que é o que eu usei no meu próprio projeto), que basicamente é apenas a conversão de um ArrayList para um Array e depois para uma Lista .
fonte
Esta é uma conversa bastante antiga e os apache commons agora estão usando um StringBuilder internamente: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line. 3045
Isso, como sabemos, melhora o desempenho, mas se o desempenho é crítico, o método usado pode ser um pouco ineficiente. Embora a interface seja flexível e permita um comportamento consistente entre os diferentes tipos de coleções, é um pouco ineficiente para Listas, que é o tipo de coleção na pergunta original.
Baseamo isso no fato de estarmos incorrendo em alguma sobrecarga que evitaríamos simplesmente iterando os elementos em um loop for tradicional. Em vez disso, há algumas coisas adicionais acontecendo nos bastidores, verificando modificações simultâneas, chamadas de método etc. O loop for aprimorado, por outro lado, resultará na mesma sobrecarga, pois o iterador é usado no objeto Iterável (a Lista).
fonte
Você pode usar um Regex para isso. Isso é tão conciso quanto possível
fonte
Que tal esta função:
funciona para qualquer tipo de coleção ...
fonte