Collections.binarySearch的返回值其实藏着一个小秘密:当返回值≥0,说明找到了,直接就是索引;如果小于0,别慌,它告诉你的不只是"没找到",还精确指出了该往哪儿插——插入点 = -(返回值) - 1,而且这个位置一定在[0, list.size()]范围内,可以直接拿来给lis
Collections.binarySearch的返回值其实藏着一个小秘密:当返回值≥0,说明找到了,直接就是索引;如果小于0,别慌,它告诉你的不只是"没找到",还精确指出了该往哪儿插——插入点 = -(返回值) - 1,而且这个位置一定在[0, list.size()]范围内,可以直接拿来给list.add()用。

很多开发者在用Collections.binarySearch时,只记住了"返回负数就是没找到",但具体怎么处理这个负数却一头雾水。其实,这个返回值设计得非常巧妙——它不仅告诉你元素是否存在,还在找不到的情况下贴心地给出了插入位置线索。关键在于理解它的计算规则。
长期稳定更新的攒劲资源: >>>点此立即查看<<<
如果目标元素就在列表中,很简单,方法直接返回该元素在已排序列表中的实际索引(从0开始)。这个值≥0,你可以直接拿来用,比如定位或读取。
这才是最精彩的部分。当元素不在列表中时,返回值是-(insertion point) - 1。这里的insertion point指的是:如果你要把这个元素插进去,同时保持列表升序,它应该放在哪个位置。换句话说,就是第一个大于等于该元素的元素下标;如果所有元素都比它小,那插入点就是list.size()。
看到了吗?负数返回值并不是随便给的,它精确地告诉你"该放哪儿"。
拿到负数返回值后,只需要做一个简单的逆向计算:插入点 = -(返回值) - 1。注意千万不要直接用Math.abs,因为-0和0没区别,而且返回值本身的正负逻辑必须区分清楚,盲目取绝对值会得到错误结果。
关键点在于,插入点永远在 [0, list.size()] 范围内,所以你不必担心越界问题,直接拿去用就好。
binarySearch 不是万能的,正确工作的前提是:列表必须已经按相同顺序排序(自然序或你指定的Comparator),并且在搜索期间不能被其他线程并发修改。否则结果完全不可预测,甚至可能抛出 ClassCastException 或 IndexOutOfBoundsException。
记住这两条前置条件,才能让 binarySearch 真正为你所用,而不是制造莫名其妙的bug。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述