これは機能するはずです:
Comparator<String> startsWithComparator = new Comparator<String>() {
public int compare(String currentItem, String key) {
if(currentItem.startsWith(key)) {
return 0;
}
return currentItem.compareTo(key);
}
};
int index = Collections.binarySearch(items, "contact.", startsWithComparator);
ただし、並べ替えとその後のバイナリ検索は、シングルパスの反復よりも効率的ではありません。
補遺:
上記の答えはあなたを助けますが、ここに別の方法があります(Scala、Googleコレクションからインスピレーションを得ています):
List<String> items = Arrays.asList("one", "two", "three", "four", "five", "six");
int index = find(items, startsWithPredicate("th"));
System.out.println(index);
public static Predicate<String> startsWithPredicate(final String key) {
return new Predicate<String>(){
@Override
public boolean apply(String item) {
return item.startsWith(key);
}
};
}
public static <T> int find(Collection<T> items, Predicate<T> predicate) {
int index = 0;
for(T item: items) {
if(predicate.apply(item)) {
return index;
}
index++;
}
return -1;
}
interface Predicate<T> {
boolean apply(T item);
}
ここで重要なのは、find()メソッドが「マッチング」ロジックに関連付けられていないことです。述語を満たす要素を見つけるだけです。したがって、たとえば、述語の別の実装を渡すことができます。'endsWith'をチェックしてfind()メソッドを実行すると、特定の文字列で終わる見つかったアイテムが返されます。さらに、find()メソッドは、あらゆるタイプのコレクションに対して機能します。必要なのは、コレクション要素タイプの要素をブール値に変換する述語だけです。単純なロジックに関するこの複数行のコードは、Javaがファーストクラス関数をサポートしていないことも示しています。