zoukankan      html  css  js  c++  java
  • 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,这是因为>>>可以提高编程的运行速度

     

  • 相关阅读:
    jvm基本结构和解析
    多态的意思
    java中对象的简单解读
    double类型和int类型的区别
    python 解析xml文件
    win10不能映射Ubuntu共享文件
    Qt程序打包
    Ubuntu boot分区文件误删,系统无法启动,怎么解
    ubuntu Boot空间不够问题“The volume boot has only 5.1MB disk space remaining”
    Ubuntu 分辨率更改 xrandr Failed to get size of gamma for output default
  • 原文地址:https://www.cnblogs.com/hahayixiao/p/14038924.html
Copyright © 2011-2022 走看看