String.replaceAll
특정 문자열을 정규식을 활용해 치환할 때 Java 에선 String.replaceAll 을 지원한다.
다만 해당 메소드는 아래와 같이 complie() 을 호출하고, Pattern 객체를 생성하는데,
이러한 과정이 내부적으로 상당한 연산량으로 이루어져 있다.
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
만약 replaceAll() 을 한 두번 수행한다면 큰 오버헤드는 없겠지만,
정규식과 대상의 관계가 1 : n 일 경우 위의 연산과정을 불필요하게 반복해 수행하게 된다.
String rnn = "0000101-345678";
Pattern pattern = Pattern.compile("(.{5}$)");
int n = 100;
while (n-- > 0) {
rnn = pattern.matcher(rnn).replaceAll("******");
// rnn = rnn.replaceAll("(.{5}$)", "******");
}
이런 경우에는 위와 같이 미리 Pattern 객체를 생성해두고, 이를 참조하는 방식으로 구현해 최적화할 수 있다.
String.replace
위의 예시들은 언제까지나 정규식을 활용하는 경우이고 일반적인 치환에서는 String.replace 를 사용하는 것이 좋다.
그러나 Java 8 에서 String.replace(CharSequence, CharSequence) 의 경우,
내부적으로 여전히 Pattern 객체를 사용하며 이는 Java 9 이상 부터 최적화되었음을 인지할 필요가 있다.
이에 Java 9 이전 버전 replace 의 대안으로 Apache Commons 라이브러리 StringUtils.replace 가 주로 사용된다.
문자열 제거
아직까지 Java 에선 String.remove 와 같은 문자열 제거에 대한 메소드를 따로 지원하지 않는다.
Java 는 빈 문자 리터럴이 존재하지 않으므로,
Java 8 에서도 충분히 최적화되어 있는 String.replace(char, char) 를 활용하기 어렵고
String.replace(value, "") 와 같은 패턴으로 구현해야 한다.
따라서 더 나은 성능적 대안으로써 Apache Commons 라이브러리의 StringUtils.remove 활용을 고려해볼 수 있다.
public String removeDot(String target) {
return StringUtils.remove(target, '.');
// return target.replace(".", "");
}
다만 위에서 언급했다시피 Java 8 이후 버전 상승에 따른 지속적인 최적화로, (replace 는 Java 13에서 대폭 개선)
제 3 라이브러리보다 표준 replace 메소드를 활용하는 것이 더 나은 선택지가 될 수 있다.
댓글