配列の全ての要素が条件を満たすならTrueを返す関数の空配列の振る舞い
話題に上がっているこの内容。
True派
Flase派
例外派
要件次第派
色々いますが、時と場合によるというのが個人的な意見。
逃げ腰な意見に感じるかもしれないが、本当にこう思っている。
ライブラリの時はTrueで、そうじゃない場合は要件次第だけど大体例外。
ライブラリの場合
ライブラリの場合Trueなのは、いわゆる`every()`や`all`などの関数がTrueを返すから。
「全ての要素が条件を満たす」という主張に反対する証拠がないからこうなっている。
Vacuous truthという概念があるので見てみるのもいいと思う。Vacuous truthには日本語の特定の訳がないので日本語の情報が少ないが。
反例が存在しない場合のみに真になるというもの。
満たさないものがあれば反証になり得るが、そうじゃないなら偽である証明ができない。
命題がそのものが存在しない場合、その命題が偽であるという証明が出来ない。
例えば、馬は全て黒色という命題の時は、黒以外の馬(白馬等)という反例でこの命題は偽になる。
しかし、ユニコーンは全て黒という命題の時、ユニコーン自体が現実には存在しないため、黒ではないという反例を見つけることは出来ない。
このときユニコーンの色は全て黒色という命題は真になる。
これってプログラム的に考えるとわかりやすいと思うのでサンプル:
public static boolean isAllOdd(int[] numbers){
for(int i = 0; i< numbers.length; i++){
int number = numbers[i];
if (number % 2 == 0 ){
return false;
}
}
return true;
}
リストの中身に偶数が存在したらfalseを返すが、配列が空ならforに入らないでtrueを返す。
これはライブラリ寄りの実装でどんな関数からも呼ばれる可能性があるため。
それ以外の場合
ライブラリじゃない実装の場合を考える。
例えば動物カフェのキャストが全て猫かどうか判断するプログラム。
こう言ったクラスだと仮定。
class Cafe {
String name;
Animal[] cast;
}
class Animal{
String Type
}
実際の判断関数。
public static boolean isAllCat(Animal[] cast){
for(int i = 0; i< cast.length; i++){
if(cast[i] != "cat"){ //本来は!"cat".equals(cast[i].getType())
return false;
}
}
return false;
}
ライブラリとしての実装だと上記のようになる。
呼び出される元のプログラムとしては、動物カフェが猫カフェか犬カフェかそれ以外の動物カフェか判断する見たいなプログラムだと仮定。
同じような全て犬か判断する`isAllDog`もあるとする。
public static void whatCafeOutput(Cafe cafe){
if(isAllCat(cafe.getCast())){
System.out.println(cafe.getName() + "は猫カフェ");
}
if(isAllDog(cafe.getCast())){
System.out.println(cafe.getName() + "は犬カフェ");
}
System.out.println(cafe.getName() + "は動物カフェ");
}
このときAnimal配列のcastが0の時をどうするかというのが仕様で決まること。
動物のキャストがいない時"{cafeの名前}は動物カフェじゃない"って出力するか、何も出力せずにreturnするか、動物カフェではないため例外処理するか。
最初に`if( cafe.getCast().length == 0)`の判定をするはず。
仕様によると言っている人たちの言葉はわかるがその人たちはこっちの使い方を想定している。
「全ての要素を満たすなら...」という関数中で処理するべきじゃない。そちらはVacuous truthを満たしているのでTrue。
上記の例はわかりやすくするために無理やり考えたものなので、適切でない部分があるかもしれませんが、ご了承ください。
allMatchを用いることで実装可能
この記事が気に入ったらサポートをしてみませんか?