2017-10-27 12 views
2

なぜコード1が動作するのですか。コード2はコンパイルされません。説明してください。コンパレータを使用したスト​​リームソートメソッド

//Code1: 
    Stream<String> s = Stream.of("AA", "BB"); 
    s.sorted(Comparator.reverseOrder()) 
      .forEach(System.out::print); 

//Code2: 
    Stream<String> s = Stream.of("AA", "BB"); 
    s.sorted(Comparator::reverseOrder) 
      .forEach(System.out::print); 

2つの違いはCODE1あるComparator.reverseOrder() CODE2 ながらを使用する最初の例はfactory-methodですので、あなたがそれを調べるときに、あなたが戻って、コンパレータを取得していることがわかります。Comparator::reverseOrder

答えて

6

コンパイラからのエラーメッセージがそれを伝えるはずです。

sorted()は、Comparatorインスタンスが必要です。 Comparator.reverseOrder()は、Comparatorインスタンスを返します。それはうまく動作します。

Comparator::reverseOrderは、ComparatorのreverseOrder()メソッドを参照するメソッドです。だからあなたのコードは基本的に言う:あなたが2つの文字列を比較する必要があるたびに、それらを比較するために引数としてそれらをComparator.reverseOrderに渡す。しかし、それはおそらく動作しません。このメソッドは引数として何も取らず、Comparatorを返します。したがって、引数として2つの文字列を取り、整数を返すと思われるComparator<String>のシグネチャと一致しません。

あなたは、このような

class Foo 
    public static int compareStrings(String s1, String s2) { 
     ... 
    } 
} 

ような方法を持っていたなら、あなたは

sorted(Foo::compareStrings) 

はcompareStringsので

に、あなたはメソッドの参照を使用して、変換することができ

sorted((s1, s2) -> Foo.compareStrings(s1, s2)) 

を使用することができ、固有の抽象メソッドComparator<String>と同様に、引数として2つの文字列を取ります。 dはintを返します。

7

を使用しています

しかし、もう一つは、あなたがこのように書くことができるmethod-referenceです:

Stream<String> s = Stream.of("AA", "BB"); 
s.sorted(() -> Comparator.reverseOrder()) // no semantic difference! 
    .forEach(System.out::print); 

をしかし、この時間はあなたがSupplier<Comparator<?>>Stream#sorted()を与えられているので、それは全体の異なる意味を持っていますが、それだけでComparator<?>

を必要とします

小側符:ストリームを変数に格納しないで直接使用します。だから私はちょうどあなたが書くとお勧めします:

Stream.of("AA", "BB") 
    .sorted(Comparator.reverseOrder()) 
    .forEach(System.out::print); 
関連する問題