java - 使用startsWith快速比较字符串

标签 java

我有以下代码:

String[] names = {"aa", ..........., "bb"};
for (int i = 0; i < names.length; i++) {
    if (names[i].toLowerCase().startsWith(query.toLowerCase()))
        c.addRow(new Object[]{i, names[i]});
}

由于数组名称可能很长,我想知道从性能角度来看编写此代码的最佳方法是什么。这样循环的复杂度是O(N)。有没有java数据结构可以更快地完成同样的事情?

最佳答案

您可以对名称进行排序,使用带有不区分大小写的比较器的二分搜索来查找潜在前缀的插入点,并遍历数组以捕获具有相同前缀的所有其他单词:

// At preparation time
Arrays.sort(names, String.CASE_INSENSITIVE_ORDER);
...
// At query time
int pos = Arrays.binarySearch(names, query, String.CASE_INSENSITIVE_ORDER);
if (pos < 0) {
    pos = -(pos+1);
}
while (pos < names.length) {
    if (names[pos].toLowerCase().startsWith(query.toLowerCase())) {
        c.addRow(new Object[]{pos, names[pos]});
        pos++;
    } else {
        break;
    }
}

Arrays.binarySearch 找到一个插入点。如果名称匹配,pos 将为非负数;否则,您需要使用以下表达式将其转换为有效索引: -(pos+1) 如果 query 是正确的前缀,则其插入点将位于前面具有匹配前缀的名字。由于 names 已排序,因此具有相同前缀的所有条目将彼此相邻。这就是为什么您可以线性遍历列表直到第一次不匹配,然后在该点停止。

关于java - 使用startsWith快速比较字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33636153/

相关文章:

java - Gremlin 通过 java 读取外部 JSON 顶点并添加到现有开放图给出了 Invalid vertexprovided 异常?

java - 通过单击列表上的项目填充文本区域

java - Webdriver 和 Chrome : DevToolsActivePort file doesn't exist

java - 使用 lambda 删除列表中的元素

java - 是否可以在 Spring Boot 中在运行时构建自定义查询?

java - 使用 Canvas 在 ImageView 上绘制文本时出现问题

java - 在 java 中打包 C 二进制文件

java - UnsatisfiedDependencyException : Error creating bean with name 'entityManagerFactory'

java - "gradle appRun"上的 Groovy NullPointerException

java - 自定义 Spring Batch 应用程序中步骤的参数