33

HashMap を反復処理して (詳細については、以前の質問を参照してください)、Map に含まれるデータで構成される文字列を作成しています。項目ごとに改行しますが、最後の項目については改行したくありません。どうすればこれを達成できますか?エントリが最後のエントリかどうかを確認するために何らかのチェックができると思っていましたが、実際にそれを行う方法がわかりません。

ありがとう!

4

16 に答える 16

73

思考プロセスを「前回を除くすべての改行を追加する」から「初回を除くすべての改行を追加する」に変更します。

boolean first = true;
StringBuilder builder = new StringBuilder();

for (Map.Entry<MyClass.Key,String> entry : data.entrySet()) {
    if (first) {
        first = false;
    } else {
        builder.append("\n"); // Or whatever break you want
    }
    builder.append(entry.key())
           .append(": ")
           .append(entry.value());
}
于 2009-01-15T20:27:26.817 に答える
72

1つの方法(Javaコードの一部を借用してくれたJon Skeetに謝罪します):

StringBuilder result = new StringBuilder();

string newline = "";  
for (Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    result.append(newline)
       .append(entry.key())
       .append(": ")
       .append(entry.value());

    newline = "\n";
}
于 2009-01-15T20:30:54.500 に答える
13

これはどうですか?

StringBuilder result = new StringBuilder();

for(Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    builder.append(entry.key())
       .append(": ")
       .append(entry.value())
       .append("\n");
}

return builder.substring(0, builder.length()-1);

Jon と Joel の例から「借用」したことへの義務的な謝罪と感謝。

于 2009-01-16T14:29:34.303 に答える
9

通常、これらの種類のものには、apache-commons-lang StringUtils#joinを使用します。これらすべての種類のユーティリティ機能を作成することはそれほど難しいことではありませんが、既存の実績のあるライブラリを再利用することをお勧めします。Apache-commonsはそのような便利なものでいっぱいです!

于 2009-01-15T20:37:09.493 に答える
5

for...each の代わりに iterator を使用すると、コードは次のようになります。

StringBuilder builder = new StringBuilder();

Iterator<Map.Entry<MyClass.Key, String>> it = data.entrySet().iterator();

while (it.hasNext()) {
    Map.Entry<MyClass.Key, String> entry = it.next();

    builder.append(entry.key())
    .append(": ")
    .append(entry.value());

    if (it.hasNext()) {
        builder.append("\n");
    }
}
于 2009-01-15T21:27:55.803 に答える
3

これはおそらくより良い例です...

final StringBuilder buf = new StringBuilder();
final String separator = System.getProperty("line.separator"); // Platform new line
for (Map.Entry<MyClass.Key,String> entry: data.entrySet()) {
    builder.append(entry.key())
       .append(": ")
       .append(entry.value())
       .append(separator);
}
// Remove the last separator and return a string to use.
// N.b. this is likely as efficient as just using builder.toString() 
// which would also copy the buffer, except we have 1 char less 
// (i.e. '\n').
final String toUse = builder.substring(0, builder.length()-separator.length()-1);
于 2010-11-25T00:19:23.217 に答える
2

これは、追加の変数の代わりに StringBuilder の length プロパティを使用する私の簡潔なバージョンです。

StringBuilder builder = new StringBuilder();

for (Map.Entry<MyClass.Key,String> entry : data.entrySet())
{
    builder.append(builder.length() > 0 ? "\n" : "")
           .append(entry.key())
           .append(": ")
           .append(entry.value());
}

(Jon と Joel の例から「借用」したことについて謝罪し、感謝します。)

于 2009-01-16T14:15:48.930 に答える
2

1 つの解決策は、StringBuilder へのカスタム ラッパーを作成することです。拡張できないため、ラッパーが必要です。

public class CustomStringBuilder {

final String separator = System.getProperty("line.separator");

private StringBuilder builder = new StringBuilder();

public CustomStringBuilder appendLine(String str){
    builder.append(str + separator);
    return this;
}

public CustomStringBuilder append(String str){
    builder.append(str);
    return this;
}

public String toString() {
    return this.builder.toString();
}

}

そのような実装:

CustomStringBuilder builder = new CustomStringBuilder();

//iterate over as needed, but a wrapper to StringBuilder with new line features.

builder.appendLine("data goes here");
return builder.toString();

これにはいくつかの欠点があります。

  • 通常「ドメイン/ビジネス」中心ではないコードを書く
  • StringUtils.join のようなオープン ソースの標準ソリューションを使用しない
  • 最終的な JDK クラスをラップするクラスを維持することを余儀なくされたため、長期にわたって更新が必要になりました。

私は StringUtils.join ソリューションを使用して、コレクションを反復処理し、コード内で軽量のビルド メソッド パターンを構築しました。

于 2011-05-12T20:23:18.167 に答える
1

foreachループがファイルを通過して、すべての文字列に新しい行を追加し、ループが終了したときに最後の新しい行を削除するとします。

于 2009-01-15T20:27:49.293 に答える
1

これが最善かどうかはわかりませんが、より簡単な方法です。

すべての値をループし、通常は文字列バッファに\nを追加します。次に、このようなことをします

sb.setLength(sb.length()-1); 
于 2009-01-15T20:29:04.957 に答える
0

クラスセパレータを使用する場合は、次のことができます

StringBuilder buf = new StringBuilder();
Separator separator = new Separator("\n");
for (Map.Entry<MyClass.Key,String> entry: data.entrySet()) {
    builder.append(separator)
       .append(entry.key())
       .append(": ")
       .append(entry.value());
}

セパレータは、最初の使用時に空の文字列で印刷され、それ以降のすべての使用時にセパレータが印刷されます。

于 2009-03-05T23:45:02.613 に答える
0

ハ!この投稿のおかげで、これを行う別の方法を見つけました。

public static class Extensions
{
    public static string JoinWith(this IEnumerable<string> strings, string separator)
    {
        return String.Join(separator, strings.ToArray());
    }
}

もちろん、これは現在 C# であり、Java は (まだ) 拡張メソッドをサポートしていませんが、必要に応じて適応させることができるはずString.Joinです。そのために。

また、これは文字列の追加の反復を行うことを意味することに注意してください。最初に配列を作成してから、それを反復して文字列を作成する必要があるためです。また、配列作成します。他の方法を使用すると、一度に 1 つの文字列のみをメモリに保持する IEnumerable を使用できる場合があります。しかし、私は余分な明快さが本当に好きです.

もちろん、拡張メソッド機能があれば、他のコードを拡張メソッドに抽象化することもできます。

于 2009-03-17T13:28:36.267 に答える
0

ここで、split を補完する join メソッドが役立ちます。これは、新しい行をセパレーターとして使用してすべての要素を結合でき、もちろん結果の最後に新しい行を追加しないためです。 ; それが、さまざまなスクリプト言語 (Javascript、PHP など) で行う方法です。

于 2009-01-23T15:39:52.310 に答える
0

これは図書館にお任せください。

import com.sun.deploy.util.StringUtils;

他の多くのものと同様に、join メソッドを持つ StringUtils があります。これは 1 行で実行できます。

StringUtils.join(list, DELIMITER);

しかし、より多くのコンテキストについては、ハッシュマップを使用してそれを行う方法を次に示します。

public static String getDelimitatedData(HashMap<String, String> data) {
    final String DELIMITER = "\n"; //Should make this a variable
    ArrayList<String> entries = new ArrayList<>();

    for (Map.Entry<String, String> entry : data.entrySet()) {
        entries.add(entry.getKey() + ": " + entry.getValue());
    }

    return StringUtils.join(entries, DELIMITER);
}
于 2015-01-16T22:25:25.900 に答える
0

空白をtrim()気にせず、StringBuilder.

ここにいくつかのコード例があります

StringBuilder sb = new StringBuilder();

for (Map.Entry<String,String> entry : myMap.entrySet()) {
    builder.append(entry.key())
           .append(": ")
           .append(entry.value())
           .append("\n");
}
return sb.toString().trim();
于 2019-09-05T14:23:07.867 に答える