Java泛型(3):泛型方法
泛型还可以同样运用在方法。是否拥有泛型方法与其所在的类是否是泛型类没有关系。
无论何时,只要你能做到,都应该尽量使用泛型方法,如果泛型方法可以取代将整个类整个类泛型化,那么就应该只使用泛型方法。
下面是几个泛型方法的例子。
(1) 利用泛型方法和可变参数列表为List添加元素
1 import java.util.ArrayList; 2 import java.util.List; 3 4 public class GenericVarargs { 5 @SafeVarargs 6 public static <T> List<T> make(T... args) { 7 List<T> result = new ArrayList<T>(); 8 for (T arg : args) { 9 result.add(arg); 10 } 11 return result; 12 } 13 }
1 // 利用泛型方法和可变参数列表为List添加元素。 2 List<Integer> result = GenericVarargs.make(1, 2, 3); 3 System.out.println(result.get(0) + "/" + result.get(1) + "/" + result.get(2)); // 1/2/3
(2) 一个更通用的对象生成器例子,可以为任何类构造一个Generator,以便用next()更方便批量生成对象
1 public interface Generator<T> { 2 T next(); 3 }
1 public class GenerateObject<T> implements Generator<T> { 2 3 private Class<T> type; 4 5 private GenerateObject(Class<T> type) { 6 this.type = type; 7 } 8 9 @Override 10 public T next() { 11 try { 12 return type.newInstance(); 13 } catch (InstantiationException | IllegalAccessException e) { 14 throw new RuntimeException(e); 15 } 16 } 17 18 public static <T> GenerateObject<T> create(Class<T> type) { 19 return new GenerateObject<T>(type); 20 } 21 }
1 public class CountedObject { 2 3 private static int count = 0; 4 5 private final long id = ++count; 6 7 public String toString() { 8 return "CountedObject " + id; 9 } 10 }
1 // 一个更通用的对象生成器例子,可以为任何类构造一个Generator,以便更方便批量生成对象 2 Generator<CountedObject> gen = GenerateObject.create(CountedObject.class); 3 for (int i = 0; i < 3; i++) { 4 System.out.println(gen.next()); 5 // CountedObject 1 6 // CountedObject 2 7 // CountedObject 3 8 }
(3) 一个Set的实用工具,可以模拟数学中交集并集的处理
1 import java.util.HashSet; 2 import java.util.Iterator; 3 import java.util.Set; 4 5 public class SetUtils { 6 7 // 两个Set取并集 8 public static <T> Set<T> union(Set<T> a, Set<T> b) { 9 Set<T> result = new HashSet<T>(a); 10 result.addAll(b); 11 return result; 12 } 13 14 // 两个Set取交集 15 public static <T> Set<T> intersection(Set<T> a, Set<T> b) { 16 Set<T> result = new HashSet<T>(a); 17 result.retainAll(b); 18 return result; 19 } 20 21 // 从MainSet减去SubSet 22 public static <T> Set<T> difference(Set<T> mainset, Set<T> subset) { 23 Set<T> result = new HashSet<T>(mainset); 24 result.removeAll(subset); 25 return result; 26 } 27 28 // 取不在交集里的值 29 public static <T> Set<T> complement(Set<T> a, Set<T> b) { 30 return difference(union(a, b), intersection(a, b)); 31 } 32 33 // 打印 34 public static <T> String printSet(Set<T> set) { 35 StringBuilder sb = new StringBuilder(); 36 Iterator<T> elem = set.iterator(); 37 while (elem.hasNext()) { 38 sb.append(elem.next()); 39 if (elem.hasNext()) { 40 sb.append(", "); 41 } 42 } 43 return sb.toString(); 44 } 45 }
1 // 一个Set的实用工具,可以模拟数学中交集并集的处理 2 Set<Integer> set1 = new HashSet<>(GenericVarargs.make(1, 2, 3, 4, 5)); 3 Set<Integer> set2 = new HashSet<>(GenericVarargs.make(4, 5, 6, 7, 8)); 4 System.out.println(SetUtils.printSet(SetUtils.union(set1, set2))); // 1, 2, 3, 4, 5, 6, 7, 8 5 System.out.println(SetUtils.printSet(SetUtils.intersection(set1, set2))); // 4, 5 6 System.out.println(SetUtils.printSet(SetUtils.difference(set1, set2))); // 1, 2, 3 7 System.out.println(SetUtils.printSet(SetUtils.difference(set2, set1)));// 6, 7, 8 8 System.out.println(SetUtils.printSet(SetUtils.complement(set1, set2))); // 1, 2, 3, 6, 7, 8