1. 程式人生 > >java中如何高效判斷陣列中是否包含某個特定的值

java中如何高效判斷陣列中是否包含某個特定的值

四種不同方式檢查陣列是否包含某個值

使用List:

public static boolean useList(String[] arr, String targetValue) {
        return Arrays.asList(arr).contains(targetValue);
    }

使用Set:

 public static boolean useSet(String[] arr, String targetValue) {
        Set<String> set = new HashSet<String>(Arrays.asList(arr));
        
return set.contains(targetValue); }

使用簡單的迴圈語句:

public static boolean useLoop(String[] arr, String targetValue) {
        for (String s : arr) {
            if (s.equals(targetValue))
                return true;
        }
        return false;
    }

使用Arrays.binarySearch()方法:

下面的程式碼是錯誤的,之所以列在下面是出於完整性考慮(四種判斷方式),binarySearch()二分查詢只能用於有序陣列。

執行下面程式,你有可能會得到異常結果;

 public static boolean useArraysBinarySearch(String[] arr, String targetValue) {
        int a = Arrays.binarySearch(arr, targetValue);
        if (a > 0)
            return true;
        else
            return false;
    }

四種實現方式對應的時間開銷

陣列大小為5:

public static void main(String[] args) {
        String[] arr = new String[] { "CD", "BC", "EF", "DE", "AB" };
        // use list
        long startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useList(arr, "A");
        }
        long endTime = System.nanoTime();
        long duration = endTime - startTime;
        System.out.println("useList: " + duration / 1000000);
        // use set
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useSet(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useSet: " + duration / 1000000);
        // use loop
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useLoop(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useLoop: " + duration / 1000000);
        // use Arrays.binarySearch()
        startTime = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            useArraysBinarySearch(arr, "A");
        }
        endTime = System.nanoTime();
        duration = endTime - startTime;
        System.out.println("useArrayBinary: " + duration / 1000000);
    }

執行結果:

useList: 13
useSet: 72
useLoop: 5
useArraysBinarySearch: 9

陣列大小為1000:

String[] arr = new String[1000];
        Random s = new Random();
        for (int i = 0; i < 1000; i++) {
            arr[i] = String.valueOf(s.nextInt());
        }

執行結果:
useList: 112 useSet: 2055 useLoop: 99 useArrayBinary: 12

結論:

從測試結果可以看出,使用簡單的迴圈語句比使用任何集合都高效,很大一部分開發人員選擇使用第一種方法(List),但這種方法其實是相對低效的。在使用集合提供的API前,需要把一個數組放到集合裡,這需要消耗一定的時間,特別是對於Set集合;(注:其實ArrayList集合的效能跟普通的迴圈語句差不多,因為對於ArrayList,轉換成集合的時候,僅僅是改變了內部的陣列索引,遍歷判斷的時候,跟普通的迴圈語句類似);

如果要使用Arrays.binarySearch()方法,前提是陣列要有序,在這個測試demo中,很顯然陣列是無序的,因此不該被使用;

事實上,如果你確實需要高效的去檢查陣列或集合中是否包含某個值,一個有序列表或者有序樹能把時間複雜度降低到O(log(n)),或者使用雜湊集合,時間複雜度為O(1);