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?
How about a Prefix tree?
refer to:
How to create a simple prefix index in Java?
http://www.toptal.com/java/the-trie-a-neglected-data-structure
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.