打字猴:1.70044477e+09
1700444770
1700444771 这也没啥说的,就是二分法搜索的Java版实现。注意看加粗字体部分,首先是获得中间索引值,我们的例子中也就是2,那索引值是2的元素值是多少呢?正好是“广州”,于是返回索引值2,正确,没问题。那我们再看看indexOf的实现,代码如下:
1700444772
1700444773 public int indexOf(Object o){
1700444774
1700444775 if(o==null){
1700444776
1700444777 //null元素查找
1700444778
1700444779 for(int i=0;i<size;i++)
1700444780
1700444781 if(elementData[i]==null)
1700444782
1700444783 return i;
1700444784
1700444785 }else{
1700444786
1700444787 //非null元素查找
1700444788
1700444789 for(int i=0;i<size;i++)
1700444790
1700444791 //两个元素是否相等,注意这里是equals方法
1700444792
1700444793 if(o.equals(elementData[i]))
1700444794
1700444795 return i;
1700444796
1700444797 }
1700444798
1700444799 //没找到,返回-1
1700444800
1700444801 return-1;
1700444802
1700444803 }
1700444804
1700444805 indexOf方法就是一个遍历,找到第一个元素值相等则返回,没什么玄机。回到我们的程序上来看,for循环的第二遍即是我们要查找的“广州”,于是就返回索引值1了,也正确,没有任何问题。
1700444806
1700444807 两者的算法都没有问题,难道是我们用错了?这还真是我们的错,因为二分法查询的一个首要前提是:数据集已经实现升序排列,否则二分法查找的值是不准确的。不排序怎么确定是在小区(比中间值小的区域)中查找还是在大区(比中间值大的区域)中查找呢?二分法查找必须要先排序,这是二分法查找的首要条件。
1700444808
1700444809 问题清楚了,藐视解决方法也很简单,使用Collections.sort排下序即可解决。但这样真的可以解决吗?想想看,元素数据是从Web或数据库中传递进来的,原本是一个有规则的业务数据,我们为了查找一个元素对它进行了排序,也就是改变了元素在列表中的位置,那谁来保证业务规则此时的正确性呢?所以说,binarySearch方法在此处受限了。当然,拷贝一个数组,然后再排序,再使用binarySeach查找指定值,也可以解决该问题。
1700444810
1700444811 使用binarySearch首先要考虑排序问题,这是我们编码人员经常容易忘记的,而且在测试期间还没发现问题(因为测试时“制造”的数据都很有规律),等到投入生产系统后才发现查找的数据不准确,又是一个大Bug产生了,从这点来看,indexOf要比binarySearch简单得多。
1700444812
1700444813 当然,使用binarySearch的二分法查找比indexOf的遍历算法性能上高很多,特别是在大数据集而且目标值又接近尾部时,binarySearch方法与indexOf相比,性能上会提升几十倍,因此在从性能的角度考虑时可以选择binarySearch。
1700444814
1700444815 注意 从性能方面考虑,binarySearch是最好的选择。
1700444816
1700444817
1700444818
1700444819
[ 上一页 ]  [ :1.70044477e+09 ]  [ 下一页 ]