如何在Java中高效地搜索排序的、巨大的、直接的缓冲区



我有一个直接缓冲区,里面有已经排序的整数(即1,1,3,3,3,7,7,…)。大多数值都会出现多次。我想找到我搜索的值的第一个位置。

  1. 是否有直接作用于缓冲区的搜索功能内置于Java中?(找不到任何东西)
  2. 如果没有,有没有像样的库提供这样的功能
  3. 如果没有,建议使用什么搜索算法来实现,假设:

    • 我的缓冲区中通常会有数百万个条目
    • 速度非常重要
    • 必须返回搜索到的数字的第一次出现
    • 我宁愿不让它修改数据,因为之后我需要原始数据

编辑:感谢所有建议Arrays.binarySearch()的海报,但据我所知,直接缓冲区通常没有后备阵列。这就是为什么我在寻找一个直接在缓冲区上工作的实现。

此外,每个值最多可能出现一千次,因此在找到着陆点后进行线性搜索可能不是很有效。不过,dasblinkenlight的比较建议可能会奏效。

最好的方法是为缓冲区编写自己的二进制搜索实现。这种方法小心地避免了与创建视图、复制大型阵列等相关的潜在性能损失,同时保持紧凑。

链接处的代码示例返回最右边的点;需要将nums[guess] > check线上的>替换为>=才能得到最左边的点。这可以节省潜在的向后线性搜索成本,或者使用"向后"Comparator,这需要将int封装到Integer对象中。

使用二进制搜索算法

ByteBuffer buffer = createByteBuffer();
IntBuffer intBuffer = buffer.asIntBuffer();

如果字节数组可以转换为int数组,请使用:

int [] array = intBuffer.array();
int index = java.util.Arrays.binarySearch(array,7);

我不知道缓冲区的内置功能(Arrays.binarySearch(...)需要将缓冲区转换为数组),但对于3.:由于缓冲区已经排序,二进制搜索可能很有用。如果你找到了这个值,你可以检查之前的值,以获得该序列的开始。

您可能需要编写自己的二进制搜索:如果检查的值与搜索的值相等,则该搜索总是向左移动。

因此,实际上,您要搜索的不是x,而是x-ε。你的算法总是需要logn(或logn+1)步,因为它总是"失败",但它会给你第一个大于x-ε的元素的索引。您所需要做的就是检查该元素是否为x,如果是,则表示您找到了匹配项,如果不是,则表示缓冲区中没有x

最新更新