欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于Collections.binarySearch的一个大坑!!!!

程序员文章站 2022-06-10 23:41:55
...

关于Collections.binarySearch的一个大坑!!!!

问题说明

众所周知,Collections类的各种方法能够提升我们的开发效率,避免重复造*。但是笔者最近使用Collections.binarySearch发现了一个大坑,各位使用该方法时请务必注意。

测试代码

package com.daisy.collection;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 
 * @Description
 */
@Slf4j
public class CollectionsTest {


    public static void main(String[] args) {
        List<String> list = init();
        Collections.reverse(list);
//        Collections.sort(list, Comparator.comparing(String::length).reversed());
        int i = Collections.binarySearch(list, "3333");
        int j = list.indexOf("3333");
        log.info("转换后的list集合{}",list);
        log.info("查询元素的位置i={}",i);
        log.info("实际的元素的位置j={}",j);

    }


    public static List<String> init(){
        List<String> list = new ArrayList<>();
        for (int i=0 ; i <10 ;i++){
            int k=0;
            StringBuilder sb = new StringBuilder();
            while(k <= i){
                k++;
             sb.append(i);
            }
            list.add(sb.toString());
        }
        log.info("新建的list={}",list);
        return list;
    }
}

返回结果

关于Collections.binarySearch的一个大坑!!!!
从这里可以看到,本来应该返回结果6,实际上返回的是 -1 !!!

深入源码分析原因

关于Collections.binarySearch的一个大坑!!!!
从这里可以看到,二分查找时,当中值小于当前值时,查找范围是向集合尾部缩小的。也就是说这里默认集合是以升序进行排序的!!!
为此我特意去看了下百度的二分查找算法的定义:

关于Collections.binarySearch的一个大坑!!!!

关于Collections.binarySearch的一个大坑!!!!
其实从这里可以看到,百度给的描述里已经默认的把集合作为了升序排列的集合,这点其实从定义上是看不出来的。

总结

以后使用,Collections.binarySearch要记得先把集合变成升序的。否则可能会出现类似笔者的情况,明明是有值的却返回-1.

ps

刚刚用了下Arrays.binarySearch也是有类似的问题

相关标签: java