目錄
最近重新整理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,這是因為>>>可以提高編程的運行速度