web-dev-qa-db-ja.com

返された値がnullでないかどうかを確認し、nullでない場合は、1行で1回のメソッド呼び出しで割り当てます

Javaには次のような文が散らばっています。

if(cage.getChicken() != null) {
    dinner = cage.getChicken();
} else {
    dinner = getFreeRangeChicken();
}

getChicken()を2回呼び出してから、返されたオブジェクトをdinnerに割り当てることができます。

これは、次のように1行で記述することもできます。

dinner = cage.getChicken() != null? cage.getChicken() : getFreeRangeChicken();

しかし残念ながら、getChicken()への呼び出しはまだ2つあります。

もちろん、ローカル変数を割り当てた後、nullでない場合は三項演算子を再度使用して割り当てることができますが、これは2行であり、あまりきれいではありません。

FutureMeal chicken = cage.getChicken();
dinner = chicken != null? chicken : getFreeRangeChicken();

だから言う方法はありますか?

変数var =ある値がnullでない場合、ある値OR他の値。

そして、私はここで構文を話しているだけだと思います。コードがコンパイルされた後、おそらくパフォーマンスの意味でコードがどのように書かれたかはそれほど違いはありません。

これは非常に一般的なコードであるため、それを書くためのワンライナーがあれば素晴らしいでしょう。

他の言語にはこの機能がありますか?

40
Continuity8

Javaには合体演算子がないため、1回の呼び出しでの割り当てには、明示的な一時を使用したコードが最適です。

次のように、結果変数を一時的なものとして使用できます。

dinner = ((dinner = cage.getChicken()) != null) ? dinner : getFreeRangeChicken();

ただし、これは読みにくいです。

48
dasblinkenlight

Lokiの答えと同じ原理ですが、短いです。短くしても自動的に良くなるわけではないことに注意してください。

dinner = Optional.ofNullable(cage.getChicken())
  .orElse(getFreerangeChicken());

注:Optionalのこの使用は、JDKの設計者およびオプション機能の設計者によって明示的に推奨されていません。新しいオブジェクトを割り当てて、毎回すぐに破棄します。しかし一方で、それは非常に読みやすくなる可能性があります。

54
jhyot

Java 1.8をまだ使用しておらず、commons-langを使用する気がない場合は、 org.Apache.commons.lang3.ObjectUtils#defaultIfNull を使用できます。

あなたのコードは次のようになります:

dinner = ObjectUtils.defaultIfNull(cage.getChicken(),getFreeRangeChicken())
11
Pieter De Bie

Java 1.8を使用すると、Optionalを使用できます

public class Main  {

    public static void main(String[] args) {

        //example call, the methods are just dumb templates, note they are static
        FutureMeal meal = getChicken().orElse(getFreeRangeChicken());

        //another possible way to call this having static methods is
        FutureMeal meal = getChicken().orElseGet(Main::getFreeRangeChicken); //method reference

        //or if you would use a Instance of Main and call getChicken and getFreeRangeChicken
        // as nonstatic methods (assume static would be replaced with public for this)
        Main m = new Main();
        FutureMeal meal = m.getChicken().orElseGet(m::getFreeRangeChicken); //method reference

        //or
        FutureMeal meal = m.getChicken().orElse(m.getFreeRangeChicken()); //method call


    }

    static Optional<FutureMeal> getChicken(){

        //instead of returning null, you would return Optional.empty() 
        //here I just return it to demonstrate
        return Optional.empty();

        //if you would return a valid object the following comment would be the code
        //FutureMeal ret = new FutureMeal(); //your return object
        //return Optional.of(ret);            

    }

    static FutureMeal getFreeRangeChicken(){
        return new FutureMeal();
    }
}

getChickenのロジックを実装して、nullの代わりにOptional.empty()を返すか、Optional.of(myReturnObject)を返します。ここで、myReturnObjectchickenです。

その後、getChicken()を呼び出すことができ、Optional.empty()を返す場合、orElse(fallback)はフォールバックが何であれ、2番目のメソッドになります。

11
Loki

自分のを使え

public static <T> T defaultWhenNull(@Nullable T object, @NonNull T def) {
    return (object == null) ? def : object;
}

例:

defaultWhenNull(getNullableString(), "");

長所

  • Java8で開発しないでください
  • API 24以前デバイスをサポートするAndroid開発に対応
  • 外部ライブラリは必要ありません

短所

  • 常にdefault valueを評価します(cond ? nonNull() : notEvaluated()に対して)

    これは、デフォルト値の代わりにCallableを渡すことで回避できますが、多少複雑で動的性が低くなります(たとえば、パフォーマンスに問題がある場合)。

    ちなみに、Optional.orElse()を使用すると同じ欠点があります;-)

1
Levit

Java 9以降、 Objects#requireNonNullElse があります。

public static <T> T requireNonNullElse(T obj, T defaultObj) {
    return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}

あなたのコードは

dinner = Objects.requireNonNullElse(cage.getChicken(), getFreeRangeChicken());

これは1行で、getChicken()を1回だけ呼び出すため、両方の要件が満たされます。

2番目の引数もnullにできないことに注意してください。このメソッドは、戻り値の非ヌルを強制します。

代替案も考慮してください Objects#requireNonNullElseGet

public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)

最初の引数がnullでない場合は2番目の引数も評価しませんが、Supplierを作成するオーバーヘッドがあります。

1
user1803551
dinner = cage.getChicken();
if(dinner == null) dinner = getFreeRangeChicken();

または

if( (dinner = cage.getChicken() ) == null) dinner = getFreeRangeChicken();
0
crashxxl

あるいは、Java8では、NullableまたはNotNull注釈を必要に応じて使用できます。

 public class TestingNullable {
        @Nullable
        public Color nullableMethod(){
            //some code here
            return color;
        }

        public void usingNullableMethod(){
            // some code
            Color color = nullableMethod();
            // Introducing assurance of not-null resolves the problem
            if (color != null) {
                color.toString();
            }
        }
    }

 public class TestingNullable {
        public void foo(@NotNull Object param){
            //some code here
        }

        ...

        public void callingNotNullMethod() {
            //some code here
            // the parameter value according to the explicit contract
            // cannot be null
            foo(null);
        }
    }

http://mindprod.com/jgloss/atnullable.html

0
shan