Item 27. 가능하면 제네릭 함수로 만들것
static 유틸리티 함수는 제네릭화하기 좋은 후보다. Collections에 구현된 모든 “알고리즘” 함수(binarySearch나 sort같은)는 제네릭으로 구현되어 있다.
1. 일반 적인 사용
public static <E> Set<E> union(Set<E> s1, Set<E> s2){
Set<E> result = new HashSet<E>(s1);
result.addAll(s2);
return result;
}
public static void main(String[] args){
Set<String> guys = new HashSet<String>(Arrays.asList("Tom", "Dick", "Harry"));
Set<String> stooges = new HashSet<String>(Arrays.asList("Larry", "Moe", "Curly"));
Set<String> aflCio = union(guys, stooges);
System.out.println( aflCio );
}
2. 제네릭 정적 팩토리 함수
Map<String, List<String>> m = new HashMap<String, List<String>>();
// 위와 같은 번거러움을 피하기 위해서 아래와 같은 제네릭 정적 함수 정리하여 사용(guava lib 사용)
public class Maps{
public static <K,V> Hashmap<K,V> newHashMap(){
return new HashMap<K,V>();
}
}
//use
public static void main(String[] args){
Map<String, List<String>> m = Maps.newHashMap();
...
}
3. 제네릭 싱글톤 팩토리 패턴
public interface UnaryFunction<T>{
T apply(T arg);
}
// 위와 같은 항등 함수(identity function)를 구현했다고 가정함
// 항등 함수는 무상태 함수이므로 필요할 때 새 함수를 만드는 것은 낭비이므로 싱글톤으로 객체 생성하여,
// 재사용하도록 아래와 같이 구현
public static final UnaryFunction<Object> IDENTITY_FUNCTION = new UnaryFunction<Object>() {
public Object apply(Object arg){ return arg; }
};
// IDENTITY_FUNCTION은 무상태 객체고 형인자는비한정 인자이므로(unbounded)
// 모든 자료형이 같은 객체를 공유해도 안전함.
@SuppressWarnings("unchecked")@
public static <T> UnaryFunction<T> identityFunction(){
return (UnaryFunction<T>) IDENTITY_FUNCTION;
}
//use
public static void main(String[] args){
String[] strings = {"jute", "hemp", "nylon"};
UnaryFunction<String> sameString = identityFunction();
for(String s : strings)
System.out.println(sameString.apply(s));
}
4. 재귀적 자료형 한정(recursive type bound)
public static <T extends Comparable<T>> T max(List<T> list){
Iterator<T> i = list.iterator();
T result = i.next();
while( i.hasNext() ){
T t = i.next();
if(0 < t.compareTo(result)){
result = t;
}
}
return result;
}
결론
- 제네릭 자료형과 마찬가지로 제네릭 함수는 클라이언트가 직접 이력 값과 반환값의 자료형을 형변환해야 하는 함수보다 사용하기 쉽고 형 안정성도 높다.
- 시간 날때 기존 함수를 제네릭 함수로 확장해 놓으면, 기존 클라이언트 코드를 깨지 않고도 새 사용자에게 더 좋은 API를 제공할수 있다.