나는이 ArrayList
나는 완전히 String으로 출력 할 것인지. 본질적 toString
으로 탭으로 구분 된 각 요소를 사용하여 순서대로 출력하고 싶습니다 . 이 작업을 수행하는 빠른 방법이 있습니까? 루프를 반복하거나 각 요소를 제거하고 문자열에 연결할 수는 있지만 매우 느릴 것이라고 생각합니다.
답변
기본적으로 루프를 사용하여 반복하는 ArrayList
것이 유일한 옵션입니다.
이 코드를 사용하지 말고, 왜이 코드가 바람직하지 않은지, 대신 어떤 코드를 사용해야하는지 확인하려면이 답변의 맨 아래를 계속 읽으십시오.
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
String listString = "";
for (String s : list)
{
listString += s + "\t";
}
System.out.println(listString);
실제로, 문자열 연결은 javac
컴파일러가 어쨌든 일련의 append
작업으로 문자열 연결을 최적화 하기 때문에 괜찮을 것 StringBuilder
입니다. for
위 프로그램 의 루프에서 바이트 코드를 디스 어셈블하는 부분은 다음과 같습니다 .
61: new #13; //class java/lang/StringBuilder
64: dup
65: invokespecial #14; //Method java/lang/StringBuilder."<init>":()V
68: aload_2
69: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: aload 4
74: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
77: ldc #16; //String \t
79: invokevirtual #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
82: invokevirtual #17; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
보다시피, 컴파일러는를 사용하여 루프를 최적화 StringBuilder
하므로 성능에 큰 문제가되지 않습니다.
(두 번째 StringBuilder
로, 루프의 각 반복에서 인스턴스화되고 있으므로 가장 효율적인 바이트 코드가 아닐 수 있습니다. 명시 적으로 인스턴스화하고 사용하면 StringBuilder
성능이 향상됩니다.)
사실, 어떤 종류의 출력 (디스크 또는 화면)이 문자열 연결의 성능에 대해 걱정하는 것보다 적어도 속도가 느릴 것이라고 생각합니다.
편집 : 주석에서 지적했듯이 위의 컴파일러 최적화는 실제로 StringBuilder
각 반복마다 새 인스턴스를 작성합니다 . (이전에 언급 한 것입니다.)
가장 최적화 된 기술 은 루프 외부의 단일 객체 만 인스턴스화하기 때문에 Paul Tomblin 의 응답 입니다.StringBuilder
for
위의 코드를 다시 작성하여 다음을 수행하십시오.
ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
StringBuilder sb = new StringBuilder();
for (String s : list)
{
sb.append(s);
sb.append("\t");
}
System.out.println(sb.toString());
이 바이트 코드에서 입증 된 것처럼 StringBuilder
루프 외부 에서 한 번만 인스턴스화하고 루프 append
내부의 메소드 를 두 번만 호출합니다 (인스턴스화 StringBuilder
및 루프 를 보여줍니다 ).
// Instantiation of the StringBuilder outside loop:
33: new #8; //class java/lang/StringBuilder
36: dup
37: invokespecial #9; //Method java/lang/StringBuilder."<init>":()V
40: astore_2
// [snip a few lines for initializing the loop]
// Loading the StringBuilder inside the loop, then append:
66: aload_2
67: aload 4
69: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
72: pop
73: aload_2
74: ldc #15; //String \t
76: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
79: pop
따라서 for
루프 내부 가 짧고 StringBuilder
각 반복마다 인스턴스를 생성 할 필요가 없으므로 실제로 손 최적화가 더 잘 수행되어야합니다 .
답변
Java 8 이상에서 :
String listString = String.join(", ", list);
list
가 String 유형이 아닌 경우, 결합 콜렉터를 사용할 수 있습니다.
String listString = list.stream().map(Object::toString)
.collect(Collectors.joining(", "));
답변
Android 에서이 작업을 수행하는 경우 TextUtils 라는 유용한 유틸리티 가 .join(String delimiter, Iterable)
있습니다.
List<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);
분명히 안드로이드 외부에서는 많이 사용하지는 않지만이 스레드에 추가 할 것이라고 생각했습니다 …
답변
Apache Commons Lang을 다운로드하고 메소드를 사용하십시오.
StringUtils.join(list)
StringUtils.join(list, ", ") // 2nd param is the separator.
물론 직접 구현할 수도 있지만 코드는 완전히 테스트되었으며 아마도 가장 좋은 구현 일 것입니다.
저는 Apache Commons 라이브러리의 열렬한 팬이며 Java 표준 라이브러리에 큰 도움이된다고 생각합니다.
답변
이것은 꽤 오래된 질문이지만 구아바 의 Joiner
수업을 사용하여 더 현대적인 답변을 추가 할 수 있다고 생각합니다 .
String joined = Joiner.on("\t").join(list);
답변
읽기 쉽고 의미있는 문자열로 List 를 변경 하는 것은 실제로 모든 사람이 직면 할 수있는 일반적인 질문입니다.
사례 1 . 클래스 경로에 아파치의 StringUtils가있는 경우 (rogerdpack 및 Ravi Wallau에서와 같이) :
import org.apache.commons.lang3.StringUtils;
String str = StringUtils.join(myList);
사례 2 . JDK (7)의 방법 만 사용하려는 경우 :
import java.util.Arrays;
String str = Arrays.toString(myList.toArray());
혼자서 바퀴를 만들지 마십시오.이 한 줄 작업에는 루프를 사용하지 마십시오.
답변
Java 5부터 빠른 원 라이너를 찾고 있다면 다음과 같이 할 수 있습니다.
myList.toString().replaceAll("\\[|\\]", "").replaceAll(", ","\t")
또한, 목적이 단지 내용을 인쇄하고 “\ t”에 대해 덜 염려한다면 다음과 같이하면됩니다.
myList.toString()
다음과 같은 문자열을 반환합니다
[str1, str2, str3]
ArrayList가 아닌 Array가있는 경우 다음과 같이 동일하게 수행 할 수 있습니다.
Arrays.toString(myList).replaceAll("\\[|\\]", "").replaceAll(", ","\t")