2015-01-04 15 views
14

でなければならない私は、私は論理AND彼らのために行っているため、複数の述語でフィルタリングする機能を作成しました:ターゲット・タイプは、機能インタフェース

@SafeVarargs 
public static <T> Stream<T> filter(Stream<T> source, Predicate<T>... predicates) { 
    return source.filter(Arrays.stream(predicates).reduce(predicates[0], Predicate::and)); 
} 

呼び出す場合:

filter(IntStream.range(0, 10).boxed(), x -> x % 2 != 0, x -> x%3 == 0).forEach(System.out::println); 

これは、正常に動作し、私のような単一の述語を渡すときしかし、3と9を出力します。

filter(IntStream.range(0, 10).boxed(), x -> x % 2 != 0).forEach(System.out::println); 

私が手コンパイルエラー:

The target type of this expression must be a functional interface 

なぜですか?私が使用に関する情報のEclipseルナバージョン1

+0

もっとコードを投稿できますか。 – Devavrata

+1

@Devavrat何のコードですか?すべてが既にポストされています...メソッドシグネチャとボディ+コンパイルエラーを生成する呼び出し。 – user2336315

+3

コンパイルはコマンドラインで動作しますか? IntelliJ 14.0.2で両方のサンプルを実行し、それぞれ「3」、「9」、「1」、「3」、「5」、「7」、「9」を得ました。それはEclipseの問題かもしれないように見えます。 – mkobit

答えて

7

これはコンパイラのコーナーケースです。 varargsを配列にラッピングするか、単に配列を渡すかを決定するには、最後の引数の型を知る必要がありますが、ラムダ式の場合は、呼び出されたメソッドのシグネチャが必要ですタイプ。しかし、ラムダ式は決して配列型ではないので何が起こるべきかは明らかであるので、javacは問題なくコンパイルします。

一つに許容可能な回避策は、メソッドをオーバーロードすることであろう。

@SafeVarargs 
public static <T> Stream<T> filter(Stream<T> source, Predicate<T>... predicates) { 
    return source.filter(
     Arrays.stream(predicates).reduce(predicates[0], Predicate::and)); 
} 
public static <T> Stream<T> filter(Stream<T> source, Predicate<T> predicate) { 
    return source.filter(predicate); 
} 

単一の効率を向上させながら、それは、呼び出し側の変更を必要としないので、これは許容される回避策であろう同時に大文字小文字を区別します。


varargsメソッドはゼロ引数を許可しますが、そのように呼び出されると失敗します。だから、あなたはどちらか、別のオーバーロードを追加する必要があります

public static <T> Stream<T> filter(Stream<T> source) { 
    return source; 
} 

またはゼロ引数のケースのための方法を安全​​に:

@SafeVarargs 
public static <T> Stream<T> filter(Stream<T> source, Predicate<T>... predicates) { 
    return Arrays.stream(predicates).reduce(Predicate::and) 
       .map(source::filter).orElse(source); 
} 
2

については

enter image description here NetBeansとEclipseの両方がJavaでラムダ式を解析の分野でのバグの数を持っています。彼らはゆっくりと固定されていますが、私が見つけた最良の回避策は次のとおりです。 1.タイプの宣言 2.それでもうまくいかない場合は、ブロック を使用してください。3.動作しない場合は、述語/関数などを実装するオブジェクト

これらは、コードを複雑にしますが、多くの状況で必要です。

0

を時々、Eclipseは「クリーン古き良きを必要とし、すべてのプロジェクトと問題の再構築します去る。

関連する問題