8

arraybooleanエントリがあります。

boolean[] myBooleanArray = new boolean[24];

現在、次のように true が含まれているかどうかを確認します。

Arrays.asList(myBooleanArray).contains(true);

これはブール値の配列をチェックする最速の方法ですか? そうでない場合、このチェックを実行する最速の方法は何ですか?

編集:

Android 4.03 Samsung S2 デバイスでアプリとして実行することにより、次のように回答のメソッドの時間を計りました。

boolean[] myBooleanArray = new boolean[24];

long startTime = System.nanoTime();
suggestedMethod(myBooleanArray);
long endTime = System.nanoTime();

long duration = endTime - startTime;
Log.i("timetest", Long.toString(duration));

5回のランでのタイムランキングは、最速が最初でした:

  1. 5334 ~ 11584 ns:

    for (boolean value : myBooleanArray) {
        if (value) {
            return true;
        }
    }
    return false;
    
  2. 160542 ~ 171417 ns:

    Arrays.asList(myBooleanArray).contains(true);
    
  3. 191833 ~ 205750 ns:

    Booleans.contains(myBooleanArray, true);
    
4

7 に答える 7

14

配列を繰り返すだけ

for(boolean value: myBooleanArray){
  if(value){ return true;}
}
return false;
于 2012-12-03T05:53:32.640 に答える
6

Guavaライブラリ (便利なものがたくさんあります)を使用している場合:

Booleans.contains(myBooleanArray, true);

( JavaDoc )

このメソッドのドキュメントには、別の方法も記載されています。boolean[]aを a に置き換えてBitSet(メモリ効率が向上するはずです)、呼び出し!bitSet.isEmpty()て、少なくとも 1 ビットが true かどうかを確認できます。

于 2012-12-03T05:58:32.527 に答える
4

一般的に言えば、List何かの配列 (または ) がある場合、その中の項目を探す最速/唯一の方法は、探しているものが見つかるまで配列を反復処理することです。これは arrays/Listの制限の 1 つです。

24 要素の配列の場合、とにかくこれについて心配する必要はありません。何百万もの項目があり、 がほとんどないtrue(またはまったくない) と予想される場合、データをクラスにカプセル化することは理にかなっています。

public class BooleanArray
{
    boolean[] arr = new boolean[SIZE]; // or get size from a constructor
    boolean anyTrue = false;

    boolean get(int index) {
        return arr[index];
    }

    boolean set(int index, boolean value) {
        arr[index] = value;
        anyTrue |= value;
    }

    boolean containsAnyTrues() {
        return anyTrue;
    }
}

繰り返しますが、24 要素の配列にはこれをお勧めしません。つまり、データ構造が予想されるユースケースをサポートする必要があるということです。予想される使用例が「多数の要素、非常にまばらなtrues、s があるかどうかを調べる必要があるtrue」場合、最速の方法に対する懸念はより関連性が高く、上記のようなデータ構造が役立ちます。

于 2012-12-03T06:01:10.153 に答える
2

この前の質問によると、両方とも配列アクセスを使用するため、拡張 for または通常の for を使用して配列を反復処理することはほとんど同じです。したがって、配列を反復処理するだけです。

public boolean containsTrue(boolean[] array){

    for(boolean val : array){
        if(val)
            return true;
    }

    return false;
}
于 2012-12-03T05:58:20.327 に答える
0

0 と 1 の配列がある場合は、すべての要素を単純に OR することができます。1 を取得すると、少なくとも 1 つの TRUE があることがわかります。

于 2012-12-03T07:18:55.093 に答える
0

配列のサイズが分かっていて、配列が大きい場合。例えば。24はかなり小さいので、改善するのは難しいでしょう。Arrays.mismatch は少し速いようです。

import java.util.Arrays;
import java.util.Random;

public class BenchMark{
    final static int N = Short.MAX_VALUE;
    static boolean[] base = new boolean[N];
    static boolean any1(boolean[] test){
        return Arrays.mismatch(base, test)==-1;
    }
    static boolean any2(boolean[] test){
        for(boolean b: test)
            if(b) return true;
        return false;
    }
    public static void main(String[] args){
        boolean[] test = new boolean[N];
        Random r = new Random(1);
        int last = 0;
        long start = System.nanoTime();
        int p = 0;
        for(int i = 0; i<100000; i++){
            test[last] = false;
            int s = r.nextInt(2);
            if(s == 0){
                last = r.nextInt(test.length);
                test[last] = true;
            } 
            if(any2(test)){
                p++;
            }
        }
        System.out.println( ( p + " in " + (System.nanoTime() - start ) / 1e9 ) + " seconds");
    }
}

適切なベンチマークを設定しませんでしたが、これによる出力は、標準のループ手法any1よりも約 4 ~ 5 倍高速であることが示されています。any2

その理由を理解するには、jdk のソース コードを調べます。安全でないクラスを使用して値を long にキャストし、long 値を比較しているように見えるvectorizedMismatchが見つかりました。

于 2020-04-23T10:49:23.557 に答える