[java] 컬렉션 / 배열 / 목록에서 쉼표로 구분 된 문자열을 만드는 가장 정교한 방법은 무엇입니까?

데이터베이스 작업을하는 동안 쿼리 문자열을 작성하고이 문자열에서 목록 / 배열 / 컬렉션의 where-clause에 몇 가지 제한을 두어야합니다. 다음과 같이 표시되어야합니다.

select * from customer
where customer.id in (34, 26, ..., 2);

문자열 모음이 있고이 문자열의 쉼표로 구분 된 목록을 하나의 문자열로 만들고자한다는 질문으로 이것을 줄임으로써 이것을 단순화 할 수 있습니다.

지금까지 사용한 내 접근 방식은 다음과 같습니다.

String result = "";
boolean first = true;
for(String string : collectionOfStrings) {
    if(first) {
        result+=string;
        first=false;
    } else {
        result+=","+string;
    }
}

그러나 이것은 매우 추한 것을 볼 수 있습니다. 특히 생성 된 문자열 (모든 SQL 쿼리처럼)이 복잡해질 때 처음 보면 어떤 일이 발생하는지 알 수 없습니다.

당신의 (더) 우아한 방법은 무엇입니까?



답변

참고 :이 답변은 11 년 전에 작성되었을 때 좋았지 만 이제는 Java 내장 클래스 만 사용하거나 유틸리티 라이브러리를 사용하여 한 줄로 더 깔끔하게 수행 할 수있는 훨씬 더 나은 옵션이 있습니다. 아래의 다른 답변을 참조하십시오.


문자열은 변경할 수 없으므로 코드에서 문자열을 변경하려는 경우 StringBuilder 클래스를 사용할 수 있습니다.

StringBuilder 클래스는 내용이 변경 될 때 더 많은 메모리를 할당하는 변경 가능한 String 객체로 볼 수 있습니다.

질문의 원래 제안은 중복 된 후행 쉼표 를 처리하여 훨씬 더 명확하고 효율적으로 작성할 수 있습니다 .

    StringBuilder result = new StringBuilder();
    for(String string : collectionOfStrings) {
        result.append(string);
        result.append(",");
    }
    return result.length() > 0 ? result.substring(0, result.length() - 1): "";


답변

Google Guava APIjoin방법을 사용하십시오 .

Joiner.on(",").join(collectionOfStrings);


답변

오늘이 작업을 수행 한 코드를 살펴 보았습니다. 이것은 AviewAnew의 답변에 대한 변형입니다.

collectionOfStrings = /* source string collection */;
String csList = StringUtils.join(collectionOfStrings.toArray(), ",");

StringUtils에 (<- commons.lang 2.x에서, 또는 commons.lang 3.X 링크 ) 우리가 사용은에서이다 아파치 코 몬즈 .


답변

루프를 작성하는 방법은 다음과 같습니다.

StringBuilder buff = new StringBuilder();
String sep = "";
for (String str : strs) {
    buff.append(sep);
    buff.append(str);
    sep = ",";
}
return buff.toString();

sep의 성능에 대해 걱정하지 마십시오. 과제는 매우 빠릅니다. 핫스팟은 어쨌든 루프의 첫 번째 반복을 벗겨내는 경향이 있습니다 (널 (null) 및 모노 / 바이 모픽 인라인 검사와 같은 이상한 항목을 처리해야하는 경우가 많으므로).

많이 사용하는 경우 (두 번 이상) 공유 방법에 넣으십시오.

SQL 문에 ID 목록을 삽입하는 방법을 다루는 stackoverflow에 대한 또 다른 질문이 있습니다.


답변

Java 8부터 다음을 사용할 수 있습니다.


답변

더 많은 요소에 대한 테스트가 있기 때문에 반복기 관용구가 우아하다는 것을 알았습니다 (간결성을 위해 null / empty 테스트 생략).

public static String convert(List<String> list) {
    String res = "";
    for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
        res += iterator.next() + (iterator.hasNext() ? "," : "");
    }
    return res;
}


답변

이에 대한 많은 수동 솔루션이 있지만 위의 Julie의 답변을 반복하고 업데이트하고 싶습니다. Google 컬렉션 Joiner 클래스를 사용하십시오 .

Joiner.on(", ").join(34, 26, ..., 2)

var args, iterables 및 array를 처리하고 하나 이상의 문자 구분 기호를 적절하게 처리합니다 (gimmel의 답변과 달리). 또한 필요한 경우 목록의 null 값을 처리합니다.