3

I'm playing around with uses of a FunctionalInterface. I've seen multiple variations of the following code everywhere:

int i = str != null ? Integer.parseInt() : null;

I'm looking for the following behaviour:

int i = Optional.of(str).ifPresent(Integer::parseInt);

But ifPresent only accepts a Supplier and Optional cannot be extended.

I have created the following FunctionalInterface:

@FunctionalInterface
interface Do<A, B> {

    default B ifNotNull(A a) {
        return Optional.of(a).isPresent() ? perform(a) : null;
    }

    B perform(A a);
}

This allows me to do this:

Integer i = ((Do<String, Integer>) Integer::parseInt).ifNotNull(str);

One can add more default methods to do things like

LocalDateTime date = (Do<String, LocalDateTime> MyDateUtils::toDate).ifValidDate(dateStr);

そして、それはうまく読みますDo [my function] and return [function return value] if [my condition] holds true for [my input], otherwise null

A次の操作を行ったときに、コンパイラが(Stringに渡されたifNotNull) とB(Integerによって返された)の型を推測できないのはなぜですかparseInt

Integer i = ((Do) Integer::parseInt).ifNotNull(str);

これにより、次の結果が得られます。

互換性のない型: 無効なメソッド参照

4

1 に答える 1

9

元の問題については、 Optional はnull許容値を処理するのに十分強力です

Integer i = Optional.ofNullable(str).map(Integer::parseInt).orElse(null);

日付の例では、次のようになります

Date date = Optional.ofNullable(str).filter(MyDateUtils::isValidDate).map(MyDateUtils::toDate).orElse(null);

型エラーについて

Integer i = ((Do<String, Integer>) Integer::parseInt).ifNotNull(str);

インターフェイスにジェネリック引数を指定Doすると、問題が解決します。問題は、Do型引数が指定されていないということは、このインターフェイスを意味Do<Object, Object>し、Integer::parseInt一致しないということです。

于 2016-07-26T10:49:00.997 に答える