概述
更快的实施:利用contains()
使用regexp可能会相对较慢。 如果您只是想检查一个案例,那么(缓慢)并不重要。 但是如果你有一个数组或数千或数十万个字符串的集合,那么事情就会变得非常缓慢。
下面介绍的解决方案不使用正则表达式,也不使用contains()(这也很慢,因为它会创建另一个字符串,并在检查后将它们抛出)。
该解决方案基于String.regionMatches()方法构建,该方法似乎未知。 它检查2 contains()区域是否匹配,但重要的是它还具有方便的Pattern参数的过载。
public static boolean containsIgnoreCase(String src, String what) {
final int length = what.length();
if (length == 0)
return true; // Empty string is contained
final char firstLo = Character.toLowerCase(what.charAt(0));
final char firstUp = Character.toUpperCase(what.charAt(0));
for (int i = src.length() - length; i >= 0; i--) {
// Quick check before calling the more expensive regionMatches() method:
final char ch = src.charAt(i);
if (ch != firstLo && ch != firstUp)
continue;
if (src.regionMatches(true, i, what, 0, length))
return true;
}
return false;
}
速度分析
这种速度分析并不意味着是火箭科学,只是粗略描述了不同方法的速度。
我比较了5种方法。
我们的containsIgnoreCase()方法。
通过将两个字符串转换为小写并调用contains()。
通过将源字符串转换为小写字母并使用预先缓存的低级子字符串调用contains()。 这个解决方案已经不那么灵活,因为它测试了一个预先定义的子字符串。
使用正则表达式(接受的答案contains() ...)
使用正则表达式,但预先创建和缓存contains().此解决方案已经不那么灵活,因为它测试预定义的子字符串。
结果(通过调用方法1000万次):
我们的方法:670毫秒
2x toLowerCase()并包含():2829 ms
1x toLowerCase()和contains(),缓存的子字符串:2446 ms
Regexp:7180毫秒
Regexp与缓存contains():1845毫秒
结果表:
RELATIVE SPEED 1/RELATIVE SPEED
METHOD EXEC TIME TO SLOWEST TO FASTEST (#1)
------------------------------------------------------------------------------
1. Using regionMatches() 670 ms 10.7x 1.0x
2. 2x lowercase+contains 2829 ms 2.5x 4.2x
3. 1x lowercase+contains cache 2446 ms 2.9x 3.7x
4. Regexp 7180 ms 1.0x 10.7x
5. Regexp+cached pattern 1845 ms 3.9x 2.8x
与小写相比,我们的方法快4倍,使用contains(),与使用正则表达式相比快10倍,即使Pattern预先缓存(并且无法检查任意子字符串的灵活性)也快3倍。
分析测试代码
如果您对分析的执行方式感兴趣,请参阅完整的可运行应用程序:
import java.util.regex.Pattern;
public class ContainsAnalysis {
// Case 1 utilizing String.regionMatches()
public static boolean containsIgnoreCase(String src, String what) {
final int length = what.length();
if (length == 0)
return true; // Empty string is contained
final char firstLo = Character.toLowerCase(what.charAt(0));
final char firstUp = Character.toUpperCase(what.charAt(0));
for (int i = src.length() - length; i >= 0; i--) {
// Quick check before calling the more expensive regionMatches()
// method:
final char ch = src.charAt(i);
if (ch != firstLo && ch != firstUp)
continue;
if (src.regionMatches(true, i, what, 0, length))
return true;
}
return false;
}
// Case 2 with 2x toLowerCase() and contains()
public static boolean containsConverting(String src, String what) {
return src.toLowerCase().contains(what.toLowerCase());
}
// The cached substring for case 3
private static final String S = "i am".toLowerCase();
// Case 3 with pre-cached substring and 1x toLowerCase() and contains()
public static boolean containsConverting(String src) {
return src.toLowerCase().contains(S);
}
// Case 4 with regexp
public static boolean containsIgnoreCaseRegexp(String src, String what) {
return Pattern.compile(Pattern.quote(what), Pattern.CASE_INSENSITIVE)
.matcher(src).find();
}
// The cached pattern for case 5
private static final Pattern P = Pattern.compile(
Pattern.quote("i am"), Pattern.CASE_INSENSITIVE);
// Case 5 with pre-cached Pattern
public static boolean containsIgnoreCaseRegexp(String src) {
return P.matcher(src).find();
}
// Main method: perfroms speed analysis on different contains methods
// (case ignored)
public static void main(String[] args) throws Exception {
final String src = "Hi, I am Adam";
final String what = "i am";
long start, end;
final int N = 10_000_000;
start = System.nanoTime();
for (int i = 0; i < N; i++)
containsIgnoreCase(src, what);
end = System.nanoTime();
System.out.println("Case 1 took " + ((end - start) / 1000000) + "ms");
start = System.nanoTime();
for (int i = 0; i < N; i++)
containsConverting(src, what);
end = System.nanoTime();
System.out.println("Case 2 took " + ((end - start) / 1000000) + "ms");
start = System.nanoTime();
for (int i = 0; i < N; i++)
containsConverting(src);
end = System.nanoTime();
System.out.println("Case 3 took " + ((end - start) / 1000000) + "ms");
start = System.nanoTime();
for (int i = 0; i < N; i++)
containsIgnoreCaseRegexp(src, what);
end = System.nanoTime();
System.out.println("Case 4 took " + ((end - start) / 1000000) + "ms");
start = System.nanoTime();
for (int i = 0; i < N; i++)
containsIgnoreCaseRegexp(src);
end = System.nanoTime();
System.out.println("Case 5 took " + ((end - start) / 1000000) + "ms");
}
}
最后
以上就是无限大山为你收集整理的java 是否大小写混合_如何在Java中以不区分大小写的方式检查String是否包含另一个String?...的全部内容,希望文章能够帮你解决java 是否大小写混合_如何在Java中以不区分大小写的方式检查String是否包含另一个String?...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复