Java 什么';String.matches和Matcher.matches之间的区别是什么?

Java 什么';String.matches和Matcher.matches之间的区别是什么?,java,Java,String.matches和Matcher.matches之间有什么区别?在性能或其他方面有什么不同吗?当然有。在预编译的regexp上创建一个Matcher,而String。matches必须在每次执行时重新编译regexp,因此运行该行代码的频率越高,它就越浪费。String.matches内部调用模式.matches(regex,str)。 问题是,每次调用它时,都会重新编译模式,这会消耗一些资源 最好只编译一次模式,然后尝试将其与所需的所有字符串匹配。 我个人使用一个Patterns类

String.matches和Matcher.matches之间有什么区别?在性能或其他方面有什么不同吗?

当然有。在预编译的regexp上创建一个
Matcher
,而
String。matches
必须在每次执行时重新编译regexp,因此运行该行代码的频率越高,它就越浪费。

String.matches
内部调用
模式.matches(regex,str)
。 问题是,每次调用它时,都会重新编译模式,这会消耗一些资源

最好只编译一次模式,然后尝试将其与所需的所有字符串匹配。
我个人使用一个Patterns类,其中包含我的应用程序中声明为final和static的所有模式

public boolean matches(String regex) {
    return Pattern.matches(regex, this);
}

public static boolean matches(String regex, CharSequence input) {
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    return m.matches();
}
如果您正在重用模式对象,那么将有一些性能优势。此外,当使用Pattern/Matcher时,您可以使用正则表达式并获得匹配的部分


底线是,如果您有一个只使用一次的正则表达式,并且不需要解析字符串来获得匹配的部分,那么就可以使用其中任何一个。但是,如果要对多个字符串使用同一个正则表达式,或者需要基于正则表达式的部分字符串,请创建一个模式并让Matcher使用它。

出于好奇,我对时差进行了这个小测试。结果表明,使用预先编译的模式比使用String.matches方法快5倍以上

import java.util.regex.Pattern;

/**
 * @author Rajind Ruparathna
 */
public class MatchesTest {
    public static void main(String Args[]) {
        String first = "@\\{message.headers\\.?([^\\}]*)\\}";
        String second = "@\\{message.headers.wolla\\}";
        long start, end, total;
        float avg;
        int NUM_OF_ITERATIONS = 100;

        Pattern pattern = Pattern.compile(first);

        total = 0;
        start = 0;
        end = 0;
        avg = 0;

        for (int i=0; i< NUM_OF_ITERATIONS; i++) {
            start = System.nanoTime();
            pattern.matcher(second).matches();
            end = System.nanoTime();
            total = total + (end - start);
        }
        avg = total/NUM_OF_ITERATIONS;
        System.out.println("Duration pre compiled: " + avg);

        total = 0;
        start = 0;
        end = 0;
        avg = 0;

        for (int i=0; i< NUM_OF_ITERATIONS; i++) {
            start = System.nanoTime();
            first.matches(second);
            end = System.nanoTime();
            total = total + (end - start);
        }
        avg = total/NUM_OF_ITERATIONS;
        System.out.println("In place compiled: " + avg);
    }
}

注意:该测试是一个快速且不干净的测试,可能不符合性能基准实践。如果您想获得高度准确的结果,请使用微型基准测试工具。

Pattern.compile编译模式,以便在执行metcher.matches时,不会一次又一次地重新编译模式。Pattern.compile预编译它。但是,如果使用string.matches,则每次执行此行时,它都会编译模式。因此,最好使用Pattern.compile。

“我个人使用一个Patterns类,其中包含我应用程序中声明为最终和静态的所有模式。”最好将模式放在实际使用的类或方法中。这样,一起更改的代码就打包在一起了。我确实同意你的看法。4年来,我的观点发生了变化:-)自己看:第2101行。性能和
Duration pre compiled: 4505.0

In place compiled:    44960.0