3

オブジェクトのリストがあり、各オブジェクトには文字列プロパティがあります。たとえば、私には がありList<Person>、それぞれPersonfirstNameプロパティがあります。次のようなコンマ区切りの引用符付き文字列を作成したいと思います。

'James', 'Lily', 'Michael'

Java には join メソッドがないように思われることを考えると (さらに、これは単純な区切り文字列よりも少し複雑です)、これを行う最も簡単な方法は何ですか? これを少しコーディングしようとしましたが、コードが非常に乱雑になり、新しい入力を使用できるようになりました。

4

9 に答える 9

21

これを同じ問題に使用しました(Apache StringUtils

String joined = "'" + StringUtils.join(arrayOrList,"','") + "'";
于 2012-03-30T18:55:57.237 に答える
3

単純かつ手動で行いたい場合は、次のようにすることができます。

String mystr = "";
for(int i = 0; i < personlist.size(); i++) {
  mystr += "\'" + personlist.get(i).firstName + "\'";
  if(i != (personlist.size() - 1)) {
    mystr += ", ";
  }
}

これで、mystr にリストが含まれます。コンマが追加されるのは、リストの最後の要素 (インデックス personlist.size() - 1) を処理していない場合のみであることに注意してください。

もちろん、これを達成するためのより洗練された効率的な方法がありますが、私の意見では、これが最も明確です。

于 2010-08-06T19:35:30.697 に答える
2

最も簡単な方法を使用してください。を持ってStringBuilder、ループしてList、各アイテムを引用符で囲み、ビルダーに追加します。さらに追加する場合は、コンマを追加します。

StringBuilder builder = new StringBuilder();
for (int i = 0; i < persons.size(); i++) {
    builder.append("'").append(persons.get(i)).append("'");
    if (i < persons.size() - 1) {
        builder.append(", ");
    }
}
String string = builder.toString();

または、Iterator:を使用することもできます。

StringBuilder builder = new StringBuilder();
for (Iterator<Person> iter = persons.iterator(); iter.hasNext();) {
    builder.append("'").append(iter.next()).append("'");
    if (iter.hasNext()) {
        builder.append(", ");
    }
}
String string = builder.toString();

StringBuilder文字列連結を使用するよりもaを使用する方が好ましいことに注意してください+=。後者は、ヒープ上に新しい文字列インスタンスを暗黙的に作成します。これは、アイテムが多い場合にパフォーマンスとメモリを大量に消費する可能性があります。

于 2010-08-06T19:37:21.750 に答える
2

Jdk8 ラムダのソリューション:

String quotedAndDelimited = Arrays.stream(values).collect(Collectors.joining("\",\"","\"","\""));

これにより、"," が区切られ、プレフィックスとサフィックスとして ".

于 2016-06-23T13:18:46.623 に答える
1

好き

if (list != null) {
  Iterator iter = list.iter();
  if (iter.hasNext()) {
    buffer.append(iter.next());
    while (iter.hasNext()) {
      buffer.append(", ");
      buffer.append(iter.next());
    }
  }
}

これの主な利点は、実行時間の90%がおそらく内側のwhileループで行われることです。このソリューションでは、内側のwhileループを終了する必要があるかどうかを判断するために1回の比較のみが必要です。

他のソリューションも機能しますが、次のようなソリューションです。

while (iter.hasNext()) {
  buffer.append(iter.next());
  if (iter.hasNext()) {
    buffer.append(", ");
  }
}

whileループ内に不要なifステートメントを埋め込みます。これは、異なる要素が最後の要素のみである場合、要素ごとに追加の比較を行う必要があることを意味します。

要素が最後のものであるかどうかを確認するための比較を、複数の要素がある場合の比較にシフトすることにより、最初以外の各要素の付加された「、」を付加された「、」に移動するだけで済みます。

于 2010-08-06T19:52:05.373 に答える
1

これが期待されるユニットテストです:

import static java.util.Arrays.*;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;   
import org.junit.Test;


public class JoinerTest {

    private static final Converter<Person, String> PERSON_CONVERTER =
        new Converter<Person, String>() {
            @Override
            public String convert(Person object) {
                return object.getFirstName();
            }
    };

    @Test
    public void shouldPresentFirstNames() {
        // given
        Person person1 = new Person();
        person1.setFirstName("foo");
        Person person2 = new Person();
        person2.setFirstName("bar");
        Joiner<Person> joiner = new Joiner<Person>(", ", "\'");

        // when
        String firstNames = joiner.join(PERSON_CONVERTER,
                        asList(person1, person2));

        // then
        assertThat(firstNames, is("\'foo\', \'bar\'"));
    }

}

Converter は単なるインターフェースです。

public interface Converter<F, T> {
    T convert(F object);
}

そして最後にジョイナー:

public class Joiner<T> {

    private final String delimiter;

    private final String quote;

    public Joiner(String delimiter, String quote) {
        this.delimiter = delimiter;
        this.quote = quote;
    }

    public String join(Converter<T, String> converter, Iterable<T> objects) {
        StringBuilder builder = new StringBuilder();
        for (T object : objects) {
            String string = converter.convert(object);
            builder.append(quote);
            builder.append(string);
            builder.append(quote);
            builder.append(delimiter);
        }
        if (builder.length() > 0) {
            builder.setLength(builder.length() - delimiter.length());
        }
        return builder.toString();
    }
}

異なるコンバーターを使用すると、異なるタイプのプロパティを簡単に結合できます。

于 2010-08-06T22:39:44.070 に答える
0

ループ内で条件付き評価を行わないコアJava(外部依存関係なし)に実装された単純なソリューションは、次のようになります。

private static final char QUOTE = '\'';
private static final String SEPARATOR = ", ";

public static String join(List<Person> people) {
    if (people.isEmpty()) {
        return "";
    }
    final StringBuilder builder = new StringBuilder();
    for (Person person : people) {
        builder.append(QUOTE);
        builder.append(person.getFirstName());
        builder.append(QUOTE);
        builder.append(SEPARATOR);
    }
    builder.setLength(builder.length() - SEPARATOR.length());
    return builder.toString();
}

StringBufferを使用すると、Javaではパフォーマンスが低下する多くの文字列連結を回避できます。

于 2010-08-06T19:38:55.637 に答える
0

リスト内の各項目をループし、StringBuilder.append()メソッドを使用して各名前をリストに追加できます。これは、文字列が不変であるため、毎回文字列の新しいインスタンスを作成する文字列クラスを使用することを目的としています。

1)文字列ビルダーを初期化します。2)List.size()を使用してリスト内のアイテムの数を取得します。

int listSize = personList.size()

3)最初のオープニングパレンと引用符を文字列に追加します

StringBuilderinstance.append("('")

4)forループを使用して、各名前、終了引用符、コンマ、開始引用符をstringBuilderインスタンスに追加します。その後、appendメソッドを呼び出して、最後のインデックスにいる場合はlistSizeと等しいかどうかを確認し、名、引用符、および終了のみを追加します。パレン:

for(int i = 0, i<listSize, i++)
{    
    if(i == listSize - 1)
        StringBuilderinstance.append(firstName + "')")
    else    
        StringBuilderinstance.append(firstName + "', '")
}
于 2010-08-06T19:39:58.327 に答える
0

Person最初にクラスにメソッドを追加することをお勧めします。

Person {
    //...
    String toListEntry() {
        return "\'" + firstName + "\'";
    }
}

これで、これを使用できます。

List<Person> list = //... get the list
StringBuilder buf = new StringBuilder(list.get(0).toListEntry());

for(int i = 1; i < list.size(); i++)
    buf.append(" , " + list.get(i).toListEntry());

String stringList = buf.toString();
于 2010-08-06T20:24:39.873 に答える