简体   繁体   中英

Quick comparison strings with startsWith

I have the following code:

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]});
}

Since the array names can be long, I'm wondering what is the best way to write this code from performance point of view. In this way the loop is O(N). Is there any java data structure to do the same thing in a quicker way?

You can order the names, use binary search with a case-insensitive comparator to find the insertion spot for the potential prefix, and walk the array to catch all other words with the same prefix:

// 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 finds an insertion point . If the name matches, pos would be non-negative; otherwise, you need to convert it to a valid index with this expression: -(pos+1) If query is a proper prefix, its insertion point would be in front of the first name with a matching prefix. Since names is sorted, all entries with the same prefix would be next to each other. That's why you can walk the list linearly until first mismatch, and stop at that point.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM