如何在Java中有效地搜索有序,巨大的直接缓冲区?

时间:2012-03-30 14:14:24

标签: java search buffer

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

  1. 是否有直接使用缓冲区的搜索功能 内置Java? (找不到任何东西)
  2. 如果没有,是否有任何体面的图书馆提供此类功能?
  3. 如果没有,那么建议实施哪种搜索算法:

    • 我的缓冲区通常会有数百万条目
    • 速度非常重要
    • 必须返回搜索到的号码的第一个匹配项
    • 我宁愿不修改数据,因为我之后需要原始数据
  4. 编辑:感谢所有提示Arrays.binarySearch()的海报,但据我所知,直接缓冲区通常没有支持数组。这就是我寻找直接适用于缓冲区的实现的原因。

    此外,每个值最多可以发生一千次,因此在找到着陆点后进行线性搜索可能效率不高。 dasblinkenlight的比较建议可能会起作用。

4 个答案:

答案 0 :(得分:3)

最好的方法是为缓冲区编写自己的Binary Search实现。这种方法可以小心避免与创建视图,复制大型数组等相关的潜在性能问题,同时保持紧凑。

链接处的代码示例返回最右边的点;您需要将>替换为>=行上的nums[guess] > check以获取最左侧的点。这可以为您节省成本高昂的向后线性搜索,或使用“向后”Comparator,这需要将int包装到Integer个对象中。

答案 1 :(得分:2)

使用Binary search algorithm

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

您可能必须编写自己的二分搜索:如果选中的值等于搜索的值,则始终向左移动。

如果有效而不是x,您将搜索x-ε。您的算法将始终采用完全logn(或logn + 1)步骤,因为它总是“失败”,但它将为您提供大于x-ε的第一个元素的索引。您需要做的就是检查该元素是否为x,如果是,您找到了匹配项,如果不匹配,则缓冲区中没有x