这可能不是解决您的特定问题的最佳方法,但您可以使用String.matches(String regex) 方法或匹配器等效方法。我们只需要根据您的预期标题构造一个正则表达式。这里变得复杂了。
List<DVD> matchingDvds(String titleFragment) {
String escapedFragment = Pattern.quote(titleFragment);
// The pattern may have contained an asterisk, dollar sign, etc.
// For example, M*A*S*H, directed by Robert Altman.
Pattern pat = Pattern.compile(escapedFragment, Pattern.CASE_INSENSITIVE);
List<DVD> foundDvds = new ArrayList<>();
for (DVD dvd: catalog) {
Matcher m = pat.matcher(dvd.getTitle());
if (m.find()) {
foundDvds.add(dvd);
}
}
return foundDvds;
}
但这是低效的,而且纯粹是在 Java 中完成的。您最好尝试以下技术之一:
- 了解
Collator 和CollationKey 课程。
- 如果您别无选择,只能留在 Java 世界,请在 DVD 中添加一个方法,
boolean matches(String fragment)。让 DVD 告诉您匹配的内容。
- 使用数据库。如果它支持不区分大小写的排序规则,则以这种方式声明
DVD 表的title 列。使用 JDBC 或 Hibernate 或 JPA 或 Spring Data,任您选择。
- 如果数据库支持高级文本搜索,如 Oracle,请使用它。
- 回到 Java 世界,使用
Apache Lucene 和可能的 Apache Solr。
- 使用针对不区分大小写匹配而调整的语言。
如果您可以等到 Java 8,请使用 lambda 表达式。您可以通过这种方式构建正则表达式来避免我在上面使用的 Pattern 和 Matcher 类:
String escapedFragment = Pattern.quote(titleFragment);
String fragmentAnywhereInString = ".*" + escapedFragment + ".*";
String caseInsensitiveFragment = "(?i)" + fragmentAnywhereInString;
// and in the loop, use:
if(dvd.getTitle().matches(caseInsensitiveFragment)) {
foundDvds.add(dvd);
}
但这编译模式的次数太多了。小写的一切呢?
if (dvd.getTitle().toLowerCase().contains(titleFragment.toLowerCase()))
恭喜;你刚刚发现了土耳其问题。除非您在 toLowerCase 中声明语言环境,否则 Java 会找到当前语言环境。而且小写字母很慢,因为它必须考虑土耳其的无点 i 和带点 I。至少你没有模式和匹配器。