2016-09-20 32 views
1

私はJava 8の初心者です。今日は私の最初のlambdaという表現から始めました。私はString配列を持っています。ソートの前後に値を表示したいのですが。私のコードは以下の通りですstream has already operated upon or closedはに2回書いたので、forEachを2度使用しています。並べ替え前と並べ替え後の値のストリーム

import java.util.stream.Stream; 
class FirstLambda { 
    public static void main(String [] args){ 
     String [] friends = new String [] {"C","A","B","D"}; 

     Stream<String> friendsStream = Stream.of(friends); 

     System.out.println("My Friends:-"); 
     printStream(friendsStream); 

     System.out.println("My Friends (after sort):- "); 
     Stream<String> sortedFriends = friendsStream.sorted((String m,String n) -> m.compareTo(n)); 
     printStream(sortedFriends); 
    } 

    private static void printStream(Stream<String> stream) { 
     stream.forEach(s->System.out.println(s)); 
    } 
} 

私の質問は、私の問題を解決する最も簡単な方法は何ですか?それは前とソート各Stream一つだけの端末操作を持つことができますjava 8Stream(すなわち。ラムダ)

+2

あなただけの理由で、並べ替えることがないラムダと ')(' friendsStream.sorted使用することができますデフォルトでは 'compareTo'メソッドを使用します。解決策は、2つの異なる「ストリーム」オブジェクトを使用することです。 – 4castle

+0

私は同意します。しかし、ソート前とソート後に値をどのように表示するのですか? – Sridhar

+1

@Sridhar *解決策は、2つの異なるStreamオブジェクトを使用することです。* –

答えて

3

あなたが聞いて、それから「私の問題を解決するための最も簡単なまたは最良の方法です何?」答えはストリームをまったく必要としないということです。

String[] friends = {"C", "A", "B", "D"}; 
System.out.println("My Friends: "+Arrays.toString(friends)); 
Arrays.sort(friends); 
System.out.println("My Friends (after sort): "+Arrays.toString(friends)); 

Collection APIで同じ働きがあることに注意してください:

List<String> friends = Arrays.asList("C", "A", "B", "D"); 
System.out.println("My Friends: "+friends); 
friends.sort(Comparator.naturalOrder()); 
System.out.println("My Friends (after sort): "+friends); 

ストリームAPIをインポートする場合は、いくつかの方法があります。最も簡単:

String[] friends = {"C", "A", "B", "D"}; 
System.out.println("My Friends: "); 
Arrays.stream(friends).forEachOrdered(System.out::println); 
System.out.println("My Friends (after sort): "); 
Arrays.stream(friends).sorted().forEachOrdered(System.out::println); 

Arrays.streamint[]long[]double[]ために働く既存のアレイのストリームを構築するための好ましい方法は、Stream.ofを有するストリームを構築する正規の方法であるのに対して、であることに注意してください与えられた引数、の可変引数の機能を使用します。 Stream.of("C", "A", "B", "D")

は、我々は単一のストリームを使用してストリームに覗き見、次のバリアントのためにこれを使用することができます。

Stream.of("C", "A", "B", "D") 
     .peek(System.out::println) 
     .sorted() 
     .forEachOrdered(System.out::println); 

しかし、それは彼らが処理される要素を見てことができますようpeekは、ストリーム処理をデバッグするための主であることに注意してください。

しかし、あなたはストリームAPIを理解したい場合は、すべての操作がforEach/forEachOrdered最後まで唯一の代替ループを書く方法と、多くの場合よりも、より複雑な方法であること組み込むものとして、forEachまたはforEachOrderedを使用しないでください。実際の意図した操作が印刷する文字列を構成することであることを考えると

、より洗練された使用法は次のようになります。

String[] friends = {"C", "A", "B", "D"}; 
System.out.println("My Friends: " 
    +Arrays.stream(friends).collect(Collectors.joining(", "))); 
System.out.println("My Friends (after sort): " 
    +Arrays.stream(friends).sorted().collect(Collectors.joining(", "))); 
+0

私はそのシングルストリームが覗いているのが気に入っています.. awesome – Sridhar

+3

しかし、これは主に、どのように要素が処理されるか、 learn( 'sort'はすべてのソース要素の処理を強制して、' forEachOrdered'端末がそれらを処理する前に実行されます。これは他のほとんどの中間演算が動作する方法ではありません。例えば、 'sort'の代わりに' filter'を試してください。デバッグには適していますが、プロダクションコードには適切なソリューションではありません。 – Holger

+1

'Collectors.joining'を使うのが気に入らないのは、印刷前にメモリに1つの巨大な文字列を作成するということです。したがって、 'System.out'に直接印刷すると効率的ではありません。 – 4castle

2

を使用した後に文字列値を印刷しています。 forEachは端末操作なので、printStreamを使用するたびに別のStreamオブジェクトを使用する必要があります。ソート前

いずれかを使用しStream、およびソート後に別のStream

import java.util.stream.Stream; 
import java.util.Arrays; 

public class FirstLambda { 
    public static void main(String [] args) { 
     String[] friends = new String[] {"C","A","B","D"}; 

     System.out.println("My Friends:-"); 
     printStream(Arrays.stream(friends)); 

     System.out.println("My Friends (after sort):- "); 
     printStream(Arrays.stream(friends).sorted()); 
    } 

    private static void printStream(Stream<?> stream) { 
     stream.forEach(System.out::println); 
    } 
} 

Ideone Demo

関連する問題