106

Javaでリストをコンマ区切りする最も明確な方法は何ですか?

私はそれを行ういくつかの方法を知っていますが、最良の方法は何であるか疑問に思っています(「最良」とは、最も効率的ではなく、最も明確および/または最短を意味します。

リストがあり、それをループして各値を出力したいと思います。各アイテムの間にコンマを印刷したいのですが、最後のアイテムの後(または最初のアイテムの前)には印刷しません。

List --> Item ( , Item ) *
List --> ( Item , ) * Item

サンプルソリューション1:

boolean isFirst = true;
for (Item i : list) {
  if (isFirst) {
    System.out.print(i);        // no comma
    isFirst = false;
  } else {
    System.out.print(", "+i);   // comma
  }
}

サンプルソリューション2-サブリストを作成します。

if (list.size()>0) {
  System.out.print(list.get(0));   // no comma
  List theRest = list.subList(1, list.size());
  for (Item i : theRest) {
    System.out.print(", "+i);   // comma
  }
}

サンプルソリューション3:

  Iterator<Item> i = list.iterator();
  if (i.hasNext()) {
    System.out.print(i.next());
    while (i.hasNext())
      System.out.print(", "+i.next());
  }

これらは最初のアイテムを特別に扱います。代わりに、最後のものを特別に扱うことができます。

ちなみに、Java 1.6での実装方法(から継承)は次のとおりList toString ですAbstractCollection

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(", ");
    }
}

最後の項目の後のコンマを避けるために、ループを早く終了します。ところで:「(このコレクション)」を見たことを思い出すのはこれが初めてです。これを誘発するコードは次のとおりです。

List l = new LinkedList();
l.add(l);
System.out.println(l);

予期しないライブラリ(正規表現?)を使用している場合でも、解決策を歓迎します。また、Java以外の言語のソリューション(たとえば、Python / Rubyには散在関数があると思います-それはどのよう実装されていますか?)。

明確化:ライブラリとは、標準のJavaライブラリを意味します。他のライブラリについては、他の言語でそれらを検討し、それらがどのように実装されているかを知りたいと思っています。

EDITツールキットは同様の質問に言及しました:Javaでの拡張forループの最後の反復

そして別の: ループの最後の要素は別の扱いに値しますか?

4

30 に答える 30

234

Java 8 以降

StringJoinerクラスとforEachメソッドの使用:

StringJoiner joiner = new StringJoiner(",");
list.forEach(item -> joiner.add(item.toString());
return joiner.toString();

Stream、およびCollectors:

return list.stream().
       map(Object::toString).
       collect(Collectors.joining(",")).toString();

Java 7 以前

#285523も参照

String delim = "";
for (Item i : list) {
    sb.append(delim).append(i);
    delim = ",";
}
于 2009-03-21T11:44:02.320 に答える
82
org.apache.commons.lang3.StringUtils.join(list,",");
于 2009-03-21T08:31:12.127 に答える
34

Java 8 には、これを行うためのいくつかの新しい方法が用意されています。

  • 上のjoin方法String
  • クラスjoiningからのストリームのコレクター。Collectors
  • StringJoinerクラス。

例:

// Util method for strings and other char sequences
List<String> strs = Arrays.asList("1", "2", "3");
String listStr1 = String.join(",", strs);

// For any type using streams and collectors
List<Object> objs = Arrays.asList(1, 2, 3);
String listStr2 = objs.stream()
    .map(Object::toString)
    .collect(joining(",", "[", "]"));

// Using the new StringJoiner class
StringJoiner joiner = new StringJoiner(", ", "[", "]");
joiner.setEmptyValue("<empty>");
for (Integer i : objs) {
  joiner.add(i.toString());
}
String listStr3 = joiner.toString();

ストリームを使用するアプローチでは、 import static java.util.stream.Collectors.joining;.

于 2014-09-02T13:26:32.183 に答える
19
Joiner.on(",").join(myList)

ジョイナー

于 2011-08-31T01:11:07.763 に答える
7

Spring Framework を使用する場合は、StringUtilsで実行できます。

public static String arrayToDelimitedString(Object[] arr)
public static String arrayToDelimitedString(Object[] arr, String delim)
public static String collectionToCommaDelimitedString(Collection coll)
public static String collectionToCommaDelimitedString(Collection coll, String delim)
于 2009-03-21T16:10:07.860 に答える
6

Java の List toString 実装に基づく:

Iterator i = list.iterator();
for (;;) {
  sb.append(i.next());
  if (! i.hasNext()) break;
  ab.append(", ");
}

次のような文法を使用します。

List --> (Item , )* Item

最初のベースではなく最後のベースにすることで、リストの終わりをチェックするのと同じテストでスキップコンマをチェックできます。これは非常にエレガントだと思いますが、明快さについてはわかりません。

于 2009-03-21T11:04:34.803 に答える
4
for(int i=0, length=list.size(); i<length; i++)
  result+=(i==0?"":", ") + list.get(i);
于 2009-03-21T08:25:36.620 に答える
3

foreach ループの 1 つのオプションは次のとおりです。

StringBuilder sb = new StringBuilder();
for(String s:list){
  if (sb.length()>0) sb.append(",");
  sb.append(s);
}
于 2010-10-26T20:41:11.423 に答える
2

(ここから私自身の答えをコピーして貼り付けてください。)ここで説明するソリューションの多くは、IMHO、特に外部ライブラリに依存するソリューションよりも少し上にあります。私がいつも使用しているコンマ区切りのリストを実現するための、すっきりとした明確なイディオムがあります。条件付き(?)演算子に依存しています:

編集:元のソリューションは正しいですが、コメントによると最適ではありません。2回目の試行:

int[] array = {1, 2, 3};
StringBuilder builder = new StringBuilder();
for (int i = 0 ;  i < array.length; i++)
       builder.append(i == 0 ? "" : ",").append(array[i]);

配列の宣言とStringBuilderを含む4行のコードで完了します。

2番目の編集:イテレータを扱っている場合:

    List<Integer> list = Arrays.asList(1, 2, 3);
    StringBuilder builder = new StringBuilder();
    for (Iterator it = list.iterator(); it.hasNext();)
        builder.append(it.next()).append(it.hasNext() ? "," : "");
于 2009-03-21T19:32:44.580 に答える
2
StringBuffer result = new StringBuffer();
for(Iterator it=list.iterator; it.hasNext(); ) {
  if (result.length()>0)
    result.append(", ");
  result.append(it.next());
}

更新: Dave Webb がコメントで述べたように、リストの最初の項目が空の文字列の場合、正しい結果が得られない可能性があります。

于 2009-03-21T08:12:48.693 に答える
2

私は通常これを行います:

StringBuffer sb = new StringBuffer();
Iterator it = myList.iterator();
if (it.hasNext()) { sb.append(it.next().toString()); }
while (it.hasNext()) { sb.append(",").append(it.next().toString()); }

Javaの実装に従って、これからこのチェックを行うと思いますが;)

于 2009-03-21T12:38:00.617 に答える
2

Groovy (JVM 上で動作) を使用できる場合:

def list = ['a', 'b', 'c', 'd']
println list.join(',')
于 2009-03-21T15:53:40.940 に答える
1

区切り文字は「、」であるため、次のいずれかを使用できます。

public class StringDelim {

    public static void removeBrackets(String string) {
        System.out.println(string.substring(1, string.length() - 1));
    }

    public static void main(String... args) {
        // Array.toString() example
        String [] arr = {"Hi" , "My", "name", "is", "br3nt"};
        String string = Arrays.toString(arr);
        removeBrackets(string);

        // List#toString() example
        List<String> list = new ArrayList<String>();
        list.add("Hi");
        list.add("My");
        list.add("name");
        list.add("is");
        list.add("br3nt");
        string = list.toString();
        removeBrackets(string);

        // Map#values().toString() example
        Map<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", "Hi");
        map.put("2", "My");
        map.put("3", "name");
        map.put("4", "is");
        map.put("5", "br3nt");
        System.out.println(map.values().toString());
        removeBrackets(string);

        // Enum#toString() example
        EnumSet<Days> set = EnumSet.allOf(Days.class);
        string = set.toString();
        removeBrackets(string);
    }

    public enum Days {
        MON("Monday"),
        TUE("Tuesday"),
        WED("Wednesday"),
        THU("Thursday"),
        FRI("Friday"),
        SAT("Saturday"),
        SUN("Sunday");

        private final String day;

        Days(String day) {this.day = day;}
        public String toString() {return this.day;}
    }
}

区切り文字が他のものである場合、これは機能しません。

于 2012-02-10T13:21:09.197 に答える
1

これは非常に短く、非常に明確ですが、私の感性に忍び寄る恐怖を与えます. また、特に文字列 (char ではない) の場合、さまざまな区切り文字に適応するのも少し厄介です。

for (Item i : list)
  sb.append(',').append(i);
if (sb.charAt(0)==',') sb.deleteCharAt(0);

インスピレーション: Java の強化された for ループの最後の繰り返し

于 2009-03-21T13:17:55.463 に答える
1

私は通常、バージョン 3 に似たものを使用します。うまく動作します c/c++/bash/... :P

于 2009-03-21T08:16:42.210 に答える
1
StringBuffer sb = new StringBuffer();

for (int i = 0; i < myList.size(); i++)
{ 
    if (i > 0) 
    {
        sb.append(", ");
    }

    sb.append(myList.get(i)); 
}
于 2009-03-23T00:42:00.443 に答える
1

少し前にブログで見つけたこのアプローチが好きです。残念ながら、ブログの名前と URL を覚えていません。

次のようなユーティリティ/ヘルパー クラスを作成できます。

private class Delimiter
{
    private final String delimiter;
    private boolean first = true;

    public Delimiter(String delimiter)
    {
        this.delimiter = delimiter;
    }

    @Override
    public String toString()
    {
        if (first) {
            first = false;
            return "";
        }

        return delimiter;
    }
}

ヘルパー クラスの使用は次のように簡単です。

StringBuilder sb = new StringBuilder();
Delimiter delimiter = new Delimiter(", ");

for (String item : list) {
    sb.append(delimiter);
    sb.append(item);
}
于 2009-03-23T15:18:36.517 に答える
1

私はこの解決策が好きです:

String delim = " - ", string = "";

for (String item : myCollection)
    string += delim + item;

string = string.substring(delim.length());

StringBuilder も利用できると思います。

于 2012-02-10T13:15:35.957 に答える
1

私はそれをコンパイルしませんでした...しかし、動作するはずです(または動作に近い)。

public static <T> String toString(final List<T> list, 
                                  final String delim)
{
    final StringBuilder builder;

    builder = new StringBuilder();

    for(final T item : list)
    {
        builder.append(item);
        builder.append(delim);
    }

    // kill the last delim
    builder.setLength(builder.length() - delim.length());

    return (builder.toString());
}
于 2009-03-22T05:57:42.503 に答える
0
if (array.length>0)          // edited in response Joachim's comment
  sb.append(array[i]);
for (int i=1; i<array.length; i++)
  sb.append(",").append(array[i]);

リストをコンマで区切る最も明確な方法に基づいていますか(Java)?

このアイデアの使用: ループの最後の要素は別の処理に値しますか?

于 2009-03-22T07:31:12.747 に答える
0
public String toString(List<Item> items)
{
    StringBuilder sb = new StringBuilder("[");

    for (Item item : items)
    {
        sb.append(item).append(", ");
    }

    if (sb.length() >= 2)
    {
        //looks cleaner in C# sb.Length -= 2;
        sb.setLength(sb.length() - 2);
    }

    sb.append("]");

    return sb.toString();
}
于 2011-11-22T15:39:35.077 に答える
0

Pythonでは簡単です

",".join(あなたのリスト)

C# では、String クラスに静的メソッドがあります。

String.Join(",", yourlistofstrings)

申し訳ありませんが、Java についてはよくわかりませんが、あなたが他の言語について尋ねたので、私はパイプしようと思いました. Javaにも似たようなものがあると確信しています。

于 2009-03-21T08:11:46.277 に答える
0

これまでのところ、再帰を使用する答えはありません...

public class Main {

    public static String toString(List<String> list, char d) {
        int n = list.size();
        if(n==0) return "";
        return n > 1 ? Main.toString(list.subList(0, n - 1), d) + d
                  + list.get(n - 1) : list.get(0);
    }

    public static void main(String[] args) {
        List<String> list = Arrays.asList(new String[]{"1","2","3"});
        System.out.println(Main.toString(list, ','));
    }

}
于 2013-03-12T20:36:49.893 に答える
0

また、区切り文字列を無条件に追加し、ループの後で末尾の余分な区切り文字を削除することもできます。次に、最初の「リストが空の場合はこの文字列を返す」を使用すると、最後のチェックを回避できます(空のリストから文字を削除できないため)

したがって、質問は実際には次のとおりです。

「ループと if が与えられた場合、これらを組み合わせる最も明確な方法は何だと思いますか?」

于 2009-03-21T09:32:42.730 に答える
0
public static String join (List<String> list, String separator) {
  String listToString = "";

  if (list == null || list.isEmpty()) {
   return listToString;
  }

  for (String element : list) {
   listToString += element + separator;
  }

  listToString = listToString.substring(0, separator.length());

  return listToString;
}
于 2010-09-07T18:53:35.007 に答える