2016-04-07 3 views
1

ラムダとストリームを初めて使用しています。私は削除された重複してソートされ、フォーマットされたArrayListを印刷しようとしています。私は次のように動作することを知っている:私はリストを持っているADFJKLXZまたは任意のランダムな文字の出力を生成しますJavaのストリームでprintfを使用する

list.stream().distinct().forEach(System.out::print); 

。しかし、私はのように見えるために私の出力は、D、F、J、K、L、X、Z

で何をしたい私はこの試みている:私は、私はおそらくまだいくつかの混乱があると思う

list.stream().distinct().forEach(System.out::printf("%s, ",)); 

をon :: なぜ上記のコードは機能しないのですか?それを修正するにはどうすればよいですか?

答えて

4

明示的なパラメータを渡している間にメソッド参照を渡そうとしていますが、これは実行できません。代わりにラムダ式を代用することができます。

list.stream().distinct().forEach(x -> System.out.printf("%s, ", x)); 

このラムダ式はコンマとスペースが続く文字を印刷しConsumerです。

メソッド参照を使用する場合は、printf呼び出しをラップする独自のメソッドを作成します。その後

public static void printWithCommaSpace(Character c) 
{ 
    System.out.printf("%s, ", c); 
} 

list.stream().distinct().forEach(YourClass::printWithCommaSpace); 
+0

それは理にかなっている。したがって、::渡すべきパラメータがない場合にのみ使用できますか? –

+2

メソッド参照は、シグネチャが呼び出されているメソッドによって予期される機能的インタフェースの型と一致する場合にのみ使用できます。この場合、 'forEach'はちょうど1つのパラメータを取る' Consumer'を必要とします。メソッド参照はメソッドの実際の呼び出しと意味的に等価ではなく、後で呼び出すことができる機能インタフェースの実装にのみ一致するため、メソッド参照は明示的なパラメータを渡すものではありません。 – rgettman

+2

実際には、 'System.out :: println'という形式のメソッド参照を使用すると、メソッドが呼び出される' System.out'で見つかった 'PrintStream'インスタンスが既に値をバインドしています。したがって、メソッド参照は多くても1つの値にバインドでき、常にメソッドが呼び出されるオブジェクトになります。また、["System.out :: println'の等価ラムダ式は何ですか?"](http://stackoverflow.com/a/28025717/2711488) – Holger

4

これはメソッドの参照がどのように働くかではないためには、単一のパラメータは、ここではそうではありませんキャプチャした値を、一致する必要があります。

どのように修正しますか?ラムダところで

list.stream().distinct().forEach(i -> System.out.printf("%s, ",i)); 

を使用して、それを行うための、より簡潔な方法はCollectors.joining

String collect = list.stream().collect(Collectors.joining(", ")); 

を使用することですそして今、あなたは、文字列の末尾に、この余分なコンマを持っていない

関連する問題