我正在尝试构建一个 Android 拨号器应用程序 (MinSDK 23)。
我想实现如下所示的联系人搜索(通常在默认拨号器应用程序和其他第三方拨号器应用程序中可用):
当我在拨号盘上输入数字时,例如245
我应该能够搜索电话号码包含“245”的联系人以及他们的姓名包含匹配数字 245 的字母组合的联系人,根据我的计算应该是 27 个唯一组合。
虽然我知道这是一个排列问题,并且我可以通过在联系人姓名上应用或“喜欢”过滤器来进行搜索,但这似乎不够有效,并且会在我不断输入时导致更多性能问题,例如245658.
我们如何有效地做到这一点?是否有任何内置搜索机制以这种方式搜索 android 联系人或存在任何更好的自定义解决方案?
最佳答案
我可以在 0.5 秒内过滤 1500 多个联系人,
您可以创建与 List
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
class Scratch {
public static void main(String[] args) {
List<String> contactList= new ArrayList<String>();
contactList.add("Jason Arnold 9875454454");
contactList.add("Joshua Ferguson 789455482121");
contactList.add("Sarah Churchill 78452165982");
contactList.add("Brandon Walsh 78452121");
contactList.add("Justin Cameron 452197821");
contactList.add("Rebecca Howard 784521983232");
contactList.add("Trevor Smith 372753221");
contactList.add("Heather Fraser 9884562145");
contactList.add("Caroline Peters 6598421");
contactList.add("Chloe Lyman");
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("2", "[2abc]");
hm.put("3", "[3def]");
hm.put("4", "[4ghi]");
hm.put("5", "[5jkl]");
hm.put("6", "[6mno]");
hm.put("7", "[7pqrs]");
hm.put("8", "[8tuv]");
hm.put("9", "[9wxyz]");
hm.put("1", "[1]");
hm.put("0", "[0]");
Instant startTime = Instant.now();
String findContact = "3727"; // todo
String regEx = "";
for (int i = 0; i < findContact.length(); i++) {
regEx = regEx + hm.get(findContact.charAt(i) + "");
}
String finalRegEx = "^"+regEx+".*$";
System.out.println("!_!_" + finalRegEx);
List<String> ll = contactList.stream().filter(s -> isMatched(s, finalRegEx))
.collect(Collectors.toList());
for (int i = 0; i < ll.size(); i++) {
System.out.println("-->: " + ll.get(i));
}
Instant current = Instant.now();
System.out.println("\nFound List size: " + ll.size());
long milliseconds = (current.toEpochMilli() - startTime.toEpochMilli());
System.out.println("\nmilliseconds: " + milliseconds);
}
private static boolean isMatched(String str, String finalRegEx) {
String[] arrOfStr = str.split("\\s");
for (String a : arrOfStr) {
if (a.toUpperCase().matches(finalRegEx.toUpperCase()))
return true;
}
return false;
}
}
结果:
Trevor Smith 372753221 (电话号码以 3727 开头)
Heather Fraser 9884562145 (作为姓氏与 3727 拨号盘键匹配)
关于安卓联系人搜索 : Using dialpad keys (alphabets combinations/permutations),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57851323/