같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 것이 좋을 때가 많다. 재사용은 빠르고 세련되다. 특히 불변 객체는 언제든 재사용할 수 있다.
생성자 대신 정적 팩터리 메서드를 제공하는 불변 클래스에서는 정적팩터리 메서드를 사용해 불필요한 객체 생성을 피할 수 있다.
new Boolean("true");
// 위(생성자) 대신 아래 코드를 사용한다
Boolean.valueOf("true");
다음과 같은 예시가 있다.
static boolean isRomanNumeral(String s){
return s.matches("^(?=.)M*(C[MD]|D?C{0,3}"
+ "((X[CL]|L?X{0,3})(I[XV]|v?I{0,3})$";
}
String.matches()의 Pattern 인스턴스는 한 번 쓰고 버려지는데, Pattern은 입력받은 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 인스턴스 생성 비용이 높고, 그래서 그 객체를 재사용해서 성능을 개선할 수 있다고 한다.
// 성능 개선
public class RomanNumerals{
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3}"
+ "((X[CL]|L?X{0,3})(I[XV]|v?I{0,3})$");
static boolean isRomanNumeral(String s){
return ROMAN.matchers(s).matches();
}
}
Long sum = 0L;
for(long i = 0; i <= Integer.MAX_VALUE; i++){
sum += i;
}
Long 타입의 sum 변수에 i를 더할 때마다 오토박싱으로 인해 불필요한 Long 인스턴스가 생성된다. 그래서 제대로 짠 코드보다 훨씬 느리다.
sum 변수를 long 타입으로 바꾸자. 저자는 Long을 사용할 때보다 실행 시간이 10배 빨라졌다고 한다.
Map인터페이스의 keySet 메서드가 반환하는 Set객체를 보면 알 수 있다.
이 코드를 실행하면 keySet2에서 1이 사라진 것을 알 수 있다.
Map<Integer, String> map = new HashMap<>();
map.put(1,"one");
map.put(2,"two");
map.put(3,"three");
Set<Integer> keySet1 = map.keySet();
Set<Integer> keySet2 = map.keySet();
keySet1.remove(1);
for (int i : keySet2){
System.out.println(i);
}