Java:深入了解數組Arrays.binarySearch方法的優缺點


目錄

背景

最近重新整理Java基礎知識,在練習數組的過程中關於Arrays.binarySearch(type[] a,type key)方法的一系列問題以及解決方法

方法介紹

  Arrays.binarySearch(type[] a,type key),第一個輸入的值為相應數據類型的數組,第二個為想要查找的數值,如果查詢到這個數值就會返回該數值的下標,如果沒有找到,則返回插入值的負數。

PS:在使用Arrays.binarySearch(type[] a,type key)方法前,需要對數組進行排序

實例

        int[] num=new int[]{5,8,3,10,1};
        //對數組進行排序
        Arrays.sort(num);
        //排序后的數組為[1,3,5,8,10]
        //查詢數組num數值為8的下標,有結果,返回下標
        int num1=Arrays.binarySearch(num,8);
        //查詢數組num數值為6的下標,無結果,返回-1或“-”(插入點)。插入點是索引鍵將要插入數組的那一點,即第一個大於該鍵的元素的索引。
        int num2=Arrays.binarySearch(num,6);
        int num3=Arrays.binarySearch(num,-6);
        //查詢數值num中下標為2到3中數值為8的下標
        int num4=Arrays.binarySearch(num,2,3,8);
        //查詢數值num中下標為1到3中數值為3的下標
        int num5=Arrays.binarySearch(num,1,3,3);
        System.out.println("查詢數組num數值為8的下標,有結果"+num1);
        System.out.println("查詢數組num數值為6的下標,無結果"+num2);
        System.out.println("查詢數組num數值為-6的下標,無結果"+num3);
        System.out.println("查詢數值num中下標為2到3中,數值為8的下標"+num4);
        System.out.println("查詢數值num中下標為2到3中,數值為3的下標"+num5);

結果

 

方法缺點:

到這一步這個方法一切都是如此簡單,我就不會寫這個博客了,但是這個方法有1個無法解決的缺點,讓我們先看一下Java自己是如何介紹這個方法的。

 對於英語不好的朋友我把第一段已經翻譯后,顯示在下面

使用二進制搜索算法在指定的整數數組中搜索指定的值。在進行此調用之前,必須對數組進行排序(就像使用{@link#sort(int[])}方法一樣)。如果不排序,則結果未定義。
如果數組包含多個具有指定值的元素,則無法保證將找到哪一個元素。

我加粗的那一行字,也就是說如果數值中有多個重復的值,它可能就無法正確定位到該位置。

實例

int[] num=new int[20];
        for (int i=0;i<num.length;i++){
            Random random=new Random();
            num[i]=random.nextInt(3)+1;
        }
        Arrays.sort(num);
        int num1=Arrays.binarySearch(num,1);
        int num2=Arrays.binarySearch(num,2);
        int num3=Arrays.binarySearch(num,3);
        System.out.println("1的下標"+num1);
        System.out.println("2的下標"+num2);
        System.out.println("3的下標"+num3);

結果

返回結果

 

 實際結果

 

 總結:所以當有多個相同的數值在數組中,Arrays.binarySearch方法無法正確找到該數值的最后一個數值的索引,或者第一個數值的索引。

原因分析

源碼查看:查看Arrays.binarySearch()方法,這里以int類型作為解說

    public static int binarySearch(int[] a, int key) {
        return binarySearch0(a, 0, a.length, key);
    }

    public static int binarySearch(int[] a, int fromIndex, int toIndex,int key) {
        rangeCheck(a.length, fromIndex, toIndex);
        return binarySearch0(a, fromIndex, toIndex, key);
    }

    // Like public version, but without range checks.
    private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {
        int low = fromIndex;
        int high = toIndex - 1;

        while (low <= high) {
            int mid = (low + high) >>> 1;
            int midVal = a[mid];

            if (midVal < key)
                low = mid + 1;
            else if (midVal > key)
                high = mid - 1;
            else
                return mid; // key found
        }
        return -(low + 1);  // key not found.
    }

 

 我們可以看到調用Arrays.binarySearch()方法實際上就是調用binarySearch0()方法,binarySearch0()方法其實是一個二分查找法,這就是為什么我們使用Arrays.binarySearch()前需要進行排序,以及多個數值相同的數,無法精確定位下標的原因。

 補充說明:

  當沒有定義int fromIndex, int toIndex時,fromIndex=0, toIndex=數組長度

為什么使用>>>(無符號位右移),而不是用>>(右移)這是避免數據過大,導致溢出

為什么使用>>>位運算符,而不是直接除以2,這是因為>>>可以提高編程的運行速度

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM