2016-08-09 4 views
0

Java 8 Streamsを使用して最後の要素にカンマで区切られた接頭辞「and」のリストを減らすか、Java 8ストリームを使用して最後の要素にのみ文字列追加プレフィックスのリストを減らす

例えば、

List<String> ls = Arrays.asList("tom","terry","john","kevin","steve"); 

String result = ls.stream().map(String::toString) 
       .collect(Collectors.joining(", ")); 

System.out.println(result); 

この文は、=> tom、terry、john、kevin、steveを表示します。しかし、私はtom、terry、john、kevin、steveのようにリストを印刷したかった。

+0

あなたは、新しい行を作成し、強調するためにインデントとして、4つのスペースを使用する必要がありますあなたのコード。それははるかに簡単に読むことができます! – sascha10000

答えて

2

2つの溶液ちょうど同様String::replaceAllを使用する場合があります。不器用な

、実際にサブリストを取る: 1位シフトするクラスを使用し

String result = ls.stream() 
      .limit(ls.size() - 1) 
      .collect(Collectors.joining(", ")) + " and " + ls.get(ls.size() - 1); 

class SbS { 
     StringBuilder sb = new StringBuilder(); 
     String s = ""; 

     @Override 
     public String toString() { 
      return sb + (s.empty() ? "" : " and " + s); 
     } 
    } 
    result = ls.stream() 
      .collect(SbS::new, 
       (a, s) -> { 
        a.sb.append(a.sb.length() == 0 ? "" : ", ").append(a.s); a.s = s; 
       }, 
       (a1, a2) -> {}).toString(); 

マインド:クラス定義が内側に配置されなければなりませんメソッドと同様です。それ以外の場合はstaticが必要です。 (a, s)のラムダは、SbSのメソッドとすることができます。並列処理のサポートは、読者(a1, a1)に委任されています。

1

ストリームではこれを簡単にはできません。

String input = "tom, terry, john, kevin, steve"; 
String result = input.replaceAll(", (\\w+)$", " and $1"); 

System.out.println(result); 

出力:

tom, terry, john, kevin and steve 
+0

'map()'は必要ではないと思います。各文字列で 'toString' ...を呼び出します。私は、この場合は、[String.join( "、"、ls)](https://docs.oracle.com/javase)を行うより冗長な方法であるため、ストリームが必要であるとは思わない/8/docs/api/java/lang/String.html#join-java.lang.CharSequence-java.lang.Iterable-) – vlaz

+0

@Vldそうです。しかし、私はOPの入力が文字列ではなく、他のオブジェクトであり、実際の状況に最も近い例であると考えています。私はたいてい、私の行の入力がどのように作成されたか無視していました。 –

+0

私はもう一度、 'ls.toString()。replaceAll(" ^。|。$ "、" ").replaceAll("、(\\ w +)$ "、" $ 1 ")'全列車の列車の難破 – Bohemian

0

ストリームAPIはこれを実現するための標準的な方法を提供していません。標準ストリームAPIを拡張する私のStreamExライブラリにはmapLastというメソッドがあり、ここで役立ちます。それはあるとして、他のすべてを残すのみ最後のストリーム要素をマッピングすることができます:

System.out.println(StreamEx.of(ls).mapLast("and "::concat).joining(", ")); 

結果は以下の通りです:

tom, terry, john, kevin, and steve 

注それがOKである前にコンマを追加「と」こと(Oxford Commaを参照してください)。あなたがそれを好き(あるいは、実際に、そのような句読点を禁じ別の言語を使用して)、それは少し長い方法で達成することができない場合:

StreamEx.of(ls) 
     .mapLastOrElse(", "::concat, " and "::concat) 
     .joining().substring(", ".length()); 
+0

オックスフォードカンマの問題は、正確に2つの要素があるときに表示されるべきではないということです。 – Holger

+0

@Holger、それは間違いなく問題です。他の言語が異なる句読規則を持つ可能性があるため、これらのすべてのケースを解決する特別なコレクタをライブラリに追加することはあまりにも具体的です。おそらく、ICU4Jのようなプロジェクトは、Java 8の指向であればそのようなコレクターを提供することができます... –

+1

特定の人間言語へのデータ構造の書式設定は、すぐに使えるソリューションでなければならないタスクではありません(また、ストリームベースにする)。 UIの場合、最新の状態では、あらかじめテンプレート文字列を組み込んだリソースバンドルを持っています... – Holger

関連する問題