programing

String 개체 목록을 연결하는 가장 좋은 방법?

copysource 2022. 7. 21. 22:13
반응형

String 개체 목록을 연결하는 가장 좋은 방법?

String 객체 목록을 연결하는 가장 좋은 방법은 무엇입니까?다음과 같이 생각하고 있습니다.

List<String> sList = new ArrayList<String>();

// add elements

if (sList != null)
{
    String listString = sList.toString();
    listString = listString.subString(1, listString.length() - 1);
}

String Builder/String Buffer 접근방식을 사용하는 것보다 더 깔끔하다는 것을 알게 되었습니다.

의견이나 코멘트는?

Apache Commons Lang에서 StringUtils.join 메서드 중 하나를 사용합니다.

import org.apache.commons.lang3.StringUtils;

String result = StringUtils.join(list, ", ");

Java 8을 사용할 수 있는 운이 좋다면 더 쉬워질 것입니다.String만 사용합니다.참가하다

String result = String.join(", ", list);

Java 8+ 사용

String str = list.stream().collect(Collectors.joining())

또는 심지어

String str = String.join("", list);

접근법은 Java의 ArrayList#toString() 구현에 의존합니다.

구현은 Java API에 문서화되어 있으며 변경될 가능성은 거의 없지만 변경될 수 있습니다.이를 직접 구현하는 것이 훨씬 더 안정적입니다(루프, String Builder, 원하는 재귀).

물론 이 접근법이 "더 깔끔하다"거나 "너무 달콤하다"거나 "돈"으로 보일 수 있지만, 제 생각에는 더 나쁜 접근법입니다.

코데핀의 답변 변형

public static String concatStringsWSep(Iterable<String> strings, String separator) {
    StringBuilder sb = new StringBuilder();
    String sep = "";
    for(String s: strings) {
        sb.append(sep).append(s);
        sep = separator;
    }
    return sb.toString();                           
}

Android용으로 개발 중인 경우 SDK에서 제공합니다.

이것이 내가 지금까지 발견한 것 중 가장 우아하고 깔끔한 방법이다.

list.stream().collect(Collectors.joining(delimiter));

Guava는 Google에서 제공하는 꽤 깔끔한 라이브러리입니다.

Joiner joiner = Joiner.on(", ");
joiner.join(sList);

Java 8의 String.join(리스트)을 선호합니다.

이 코딩 호러 블로그 엔트리를 본 적이 있습니까?

마이크로 최적화 극장의 슬픈 비극

'더 깔끔한'지 아닌지는 모르겠지만, 퍼포먼스 면에서는 그다지 중요하지 않을지도 모릅니다.

String Builder는 빠르고 효율적일 것 같습니다.

기본 형식은 다음과 같습니다.

public static String concatStrings(List<String> strings)
{
    StringBuilder sb = new StringBuilder();
    for(String s: strings)
    {
        sb.append(s);
    }
    return sb.toString();       
}

이 방법이 너무 단순할 경우(아마도 단순할 수 있음) 유사한 방법을 사용하여 다음과 같은 구분 기호를 추가할 수 있습니다.

    public static String concatStringsWSep(List<String> strings, String separator)
{
    StringBuilder sb = new StringBuilder();
    for(int i = 0; i < strings.size(); i++)
    {
        sb.append(strings.get(i));
        if(i < strings.size() - 1)
            sb.append(separator);
    }
    return sb.toString();               
}

Java ArrayList의 toString() 메서드에 의존해서는 안 된다고 할 때 이 질문에 응답한 다른 사용자들과 동의합니다.

ArrayList 상속을 .toString()- 다음에서 복사:

public String toString() {
    Iterator<E> i = iterator();
    if (! i.hasNext())
        return "[]";

    StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = i.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! i.hasNext())
            return sb.append(']').toString();
        sb.append(", ");
    }
}

직접 줄을 만드는 것이 훨씬 더 효율적일 것입니다.


사전에 문자열을 목록 형태로 집약하려면 다음과 같이 효율적으로 결합할 수 있는 고유한 방법을 제공해야 합니다.

static String join(Collection<?> items, String sep) {
    if(items.size() == 0)
        return "";

    String[] strings = new String[items.size()];
    int length = sep.length() * (items.size() - 1);

    int idx = 0;
    for(Object item : items) {
        String str = item.toString();
        strings[idx++] = str;
        length += str.length();
    }

    char[] chars = new char[length];
    int pos = 0;

    for(String str : strings) {
        str.getChars(0, str.length(), chars, pos);
        pos += str.length();

        if(pos < length) {
            sep.getChars(0, sep.length(), chars, pos);
            pos += sep.length();
        }
    }

    return new String(chars);
}

String Builder/String Buffer 접근방식을 사용하는 것보다 더 깔끔하다는 것을 알게 되었습니다.

당신이 어떤 접근법을 취했느냐에 따라 다르겠죠.

Abstract Collection #to String() 메서드는 모든 요소를 반복하여 String Builder에 추가합니다.따라서 이 메서드는 몇 줄의 코드를 저장할 수 있지만 String을 추가로 조작해야 합니다.그 트레이드오프가 좋은 것인지 아닌지는 당신에게 달려 있습니다.

에 의존하는 것보다ArrayList.toString()구현에서는 Java 8을 사용하는 경우 원라이너를 작성할 수 있습니다.

String result = sList.stream()
                     .reduce("", String::concat);

사용하고 싶은 경우StringBufferString이 아니라String::concat의 실행 시간이 있다O(n^2), 모든 데이터를 변환할 수 있습니다.String로.StringBuffer첫번째.

StringBuffer result = sList.stream()
                           .map(StringBuffer::new)
                           .reduce(new StringBuffer(""), StringBuffer::append);

루프 턴마다 새로운 스트링을 초기화하지 않고 Peter Lawrey의 답변에 대한 다음 변형

String concatList(List<String> sList, String separator)
{
    Iterator<String> iter = sList.iterator();
    StringBuilder sb = new StringBuilder();

    while (iter.hasNext())
    {
        sb.append(iter.next()).append( iter.hasNext() ? separator : "");
    }
    return sb.toString();
}

루프를 통해 매번 조건을 체크하고 딜리미터를 추가하는 것이 아니라 포인터를 이동하거나 바이트를 null로 설정하는 것이 빠르다고 가정하면(또는 Java가 StringBuilder#setLength를 구현하더라도), 다음 방법을 사용할 수 있습니다.

public static string interserse (컬렉션<?)> 컬렉션, 문자열 딜리미터){StringBuilder sb = 새 StringBuilder();for (오브젝트 항목: 컬렉션){(항목 == null)이 계속되면(항목)추가(부록);
}sb.setLength (sb.length() - 딜리미터.length());
sb.toString()을 반환한다.}

퍼포먼스와 추가할 요소의 양에 따라서는, 이 솔루션이 적절한 경우가 있습니다.요소의 양이 많으면Arraylist메모리 재할당이 다음보다 다소 느릴 수 있습니다.StringBuilder.

기능 Java 라이브러리를 사용하여 다음 항목을 Import합니다.

import static fj.pre.Monoid.stringMonoid;
import static fj.data.List.list;
import fj.data.List;

...그러면 다음과 같은 작업을 수행할 수 있습니다.

List<String> ss = list("foo", "bar", "baz");
String s = stringMonoid.join(ss, ", ");

또는 일반적인 방법으로 Strings 목록이 없는 경우 다음을 수행합니다.

public static <A> String showList(List<A> l, Show<A> s) {
  return stringMonoid.join(l.map(s.showS_()), ", ");
}

json이 당신의 의존관계에 있는 경우.사용할 수 있습니다.new JSONArray(list).toString()

Java 8에서는 다음과 같은 리듀서를 사용할 수도 있습니다.

public static String join(List<String> strings, String joinStr) {
    return strings.stream().reduce("", (prev, cur) -> prev += (cur + joinStr));
}

언급URL : https://stackoverflow.com/questions/523871/best-way-to-concatenate-list-of-string-objects

반응형