Thinking in java4 15章 泛型
来源:互联网 发布:找黑客拿股民数据库 编辑:程序博客网 时间:2024/06/05 05:33
Thinking in java4 15章 泛型
1 生成器的妙用
2 Set2的集合,操作。
//: net/mindview/util/Sets.javapackage net.mindview.util;import java.util.*;public class Sets { public static <T> Set<T> union(Set<T> a, Set<T> b) { Set<T> result = new HashSet<T>(a); result.addAll(b); return result; } public static <T> Set<T> intersection(Set<T> a, Set<T> b) { Set<T> result = new HashSet<T>(a); result.retainAll(b); return result; } // Subtract subset from superset: public static <T> Set<T> difference(Set<T> superset, Set<T> subset) { Set<T> result = new HashSet<T>(superset); result.removeAll(subset); return result; } // Reflexive--everything not in the intersection: public static <T> Set<T> complement(Set<T> a, Set<T> b) { return difference(union(a, b), intersection(a, b)); }} // /:~
3 匿名内部类和生成器的使用,构造函数为private
4 复杂数据类型,元祖的集合。方法返回多个数据
//: net/mindview/util/Tuple.java// Tuple library using type argument inference.package net.mindview.util;/** * @author zhouhanxiu * */public class Tuple { public static <A, B> TwoTuple<A, B> tuple(A a, B b) { return new TwoTuple<A, B>(a, b); } public static <A, B, C> ThreeTuple<A, B, C> tuple(A a, B b, C c) { return new ThreeTuple<A, B, C>(a, b, c); } public static <A, B, C, D> FourTuple<A, B, C, D> tuple(A a, B b, C c, D d) { return new FourTuple<A, B, C, D>(a, b, c, d); } public static <A, B, C, D, E> FiveTuple<A, B, C, D, E> tuple(A a, B b, C c, D d, E e) { return new FiveTuple<A, B, C, D, E>(a, b, c, d, e); }} // /:~
5 擦除原理,编译期间制定类型检查,迁移兼容性折中方式 边界
未指定边界对应Object,客户端代码不用改变。
6 擦除原理,运行时检查,使用isInstance 代替instanceof
7 泛型和工厂设计模式 FactoryConstraint
import java.util.HashMap;import java.util.Map;//: generics/Holder.javapublic class Holder { public static class Car { } public static class BaoMa extends Car { } /** * 泛型实现工厂方法 * * @author zhouhanxiu * */ public static abstract class FactoryCreate<T> { public abstract T createInstance(); } public static class CarFactory extends FactoryCreate<Car> { @Override public Car createInstance() { try { return Car.class.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } } public static class BaomaFactory extends FactoryCreate<BaoMa> { @Override public BaoMa createInstance() { try { return BaoMa.class.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } } /** * 限定Car子类的工厂 * * @param type * @return */ public static Car createCarInstance(Class<? extends Car> type) { try { return type.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } /** * 所有类的工厂,没有无参构造方法,调用默认构造方法。 * * @param type * @return */ public static <T> T createByTypeClass(Class<T> type) { try { return type.newInstance(); } catch (Exception e) { throw new RuntimeException(e); } } /** * 泛型单例 * * @author zhouhanxiu * @param <T> */ public static class SingleFactory<T> { private static Map<Class<?>, Object> map = new HashMap<Class<?>, Object>(); public static synchronized <T> T create(Class<T> type) { try { if (!map.containsKey(type)) map.put(type, type.newInstance()); return (T) map.get(type); } catch (Exception e) { throw new RuntimeException(e); } } } public static void main(String[] args) { Car c = createByTypeClass(Car.class); System.out.println(c); Car bm = createByTypeClass(BaoMa.class); System.out.println(bm); Car c1 = createCarInstance(Car.class); System.out.println(c1); Car bm2 = createCarInstance(BaoMa.class); System.out.println(bm2); CarFactory factory1 = new CarFactory(); Car c11 = factory1.createInstance(); System.out.println(c11); BaomaFactory factory2 = new BaomaFactory(); Car bm22 = factory2.createInstance(); System.out.println(bm22); System.out.println(SingleFactory.create(Car.class)); System.out.println(SingleFactory.create(Car.class)); }} /* * Output: (Sample) java.lang.ClassCastException: Apple cannot be cast to Orange * true */// :~
8 泛型和模板设计模式 GenericWithCreate
9 数组泛型实际是Object[], GenericArray和GenericArray2
泛型中创建数组 Array.newInstance()
《java谜题》书籍,有时间看看
10 多边界EpicBattle InheritBounds BasicBounds
11 通配符?单一边界。
12 数组和容器在泛型上的区别,
见NonCovariantGenerics和CovariantArrays 数组支持协变,容器为了协变搞了通配符。
13 协变和逆变, Product Extend Consumer Super PECS
14 上届通配符? extends 只能get(多态转换为父类),不能添加。
15 下届通配符 ? super 只能add,不能get(不知道是哪个父类)
16 自动装箱和拆箱,在泛型有一定用处,但不能解决所有问题
见PrimitiveGenericTest和作业Holders30
17 参数化接口问题,导致接口重复实现
见MultipleInterfaceVariants和**HijackedInterface的接口Comparable问题
18 自限定类型 指定自己的类型
只能强制用于继承关系,NotSelfBounded
19 自限定类型,支持协变
20 Collections 动态类型安全
Collections .checkedCollection checkedList, checkedMap,checkedSet,checkSortedMap,checkSortedSet
//: generics/CheckedList.java// Using Collection.checkedList().import typeinfo.pets.Cat;import typeinfo.pets.Pet;import typeinfo.pets.Dog;import java.util.*;public class CheckedList { @SuppressWarnings("unchecked") static void oldStyleMethod(List probablyDogs) { probablyDogs.add(new Cat()); } public static void main(String[] args) { List<Dog> dogs1 = new ArrayList<Dog>(); oldStyleMethod(dogs1); // Quietly accepts a Cat List<Dog> dogs2 = Collections.checkedList(new ArrayList<Dog>(), Dog.class); try { oldStyleMethod(dogs2); // Throws an exception } catch (Exception e) { e.printStackTrace(); } // Derived types work fine: List<Pet> pets = Collections.checkedList(new ArrayList<Pet>(), Pet.class); pets.add(new Dog()); pets.add(new Cat()); }} /* * Output: java.lang.ClassCastException: Attempt to insert class * typeinfo.pets.Cat element into collection with element type class * typeinfo.pets.Dog */// :~
21 泛型应用于异常很受限
catch不能获取E泛型的异常,只能是具体的异常,throws E 可以,见 ThrowGenericException
//: generics/ThrowGenericException.javaimport java.util.*;interface Processor<T, E extends Exception> { void process(List<T> resultCollector) throws E;}class ProcessRunner<T, E extends Exception> extends ArrayList<Processor<T, E>> { List<T> processAll() throws E { List<T> resultCollector = new ArrayList<T>(); for (Processor<T, E> processor : this) processor.process(resultCollector); return resultCollector; }}class Failure1 extends Exception {}class Processor1 implements Processor<String, Failure1> { static int count = 3; public void process(List<String> resultCollector) throws Failure1 { if (count-- > 1) resultCollector.add("Hep!"); else resultCollector.add("Ho!"); if (count < 0) throw new Failure1(); }}class Failure2 extends Exception {}class Processor2 implements Processor<Integer, Failure2> { static int count = 2; public void process(List<Integer> resultCollector) throws Failure2 { if (count-- == 0) resultCollector.add(47); else { resultCollector.add(11); } if (count < 0) throw new Failure2(); }}public class ThrowGenericException { public static void main(String[] args) { ProcessRunner<String, Failure1> runner = new ProcessRunner<String, Failure1>(); for (int i = 0; i < 4; i++) runner.add(new Processor1()); try { System.out.println(runner.processAll()); } catch (Exception e) { System.out.println(e); } ProcessRunner<Integer, Failure2> runner2 = new ProcessRunner<Integer, Failure2>(); for (int i = 0; i < 3; i++) runner2.add(new Processor2()); try { System.out.println(runner2.processAll()); } catch (Exception e) { System.out.println(e); } }} // /:~
22 动态代理实现混型
//: generics/DynamicProxyMixin.javaimport java.lang.reflect.*;import java.util.*;import net.mindview.util.*;import static net.mindview.util.Tuple.*;class MixinProxy implements InvocationHandler { Map<String, Object> delegatesByMethod; public MixinProxy(TwoTuple<Object, Class<?>>... pairs) { delegatesByMethod = new HashMap<String, Object>(); for (TwoTuple<Object, Class<?>> pair : pairs) { for (Method method : pair.second.getMethods()) { String methodName = method.getName(); // The first interface in the map // implements the method. if (!delegatesByMethod.containsKey(methodName)) delegatesByMethod.put(methodName, pair.first); } } } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); Object delegate = delegatesByMethod.get(methodName); return method.invoke(delegate, args); } @SuppressWarnings("unchecked") public static Object newInstance(TwoTuple... pairs) { Class[] interfaces = new Class[pairs.length]; for (int i = 0; i < pairs.length; i++) { interfaces[i] = (Class) pairs[i].second; } ClassLoader cl = pairs[0].first.getClass().getClassLoader(); return Proxy.newProxyInstance(cl, interfaces, new MixinProxy(pairs)); }}public class DynamicProxyMixin { public static void main(String[] args) { Object mixin = MixinProxy.newInstance( tuple(new BasicImp(), Basic.class), tuple(new TimeStampedImp(), TimeStamped.class), tuple(new SerialNumberedImp(), SerialNumbered.class)); Basic b = (Basic) mixin; TimeStamped t = (TimeStamped) mixin; SerialNumbered s = (SerialNumbered) mixin; b.set("Hello"); System.out.println(b.get()); System.out.println(t.getStamp()); System.out.println(s.getSerialNumber()); }} /* * Output: (Sample) Hello 1132519137015 1 */// :~
23 潜在类型机制 接口和泛型的优雅结合
SimpleQueue.java
//: generics/SimpleQueue.java// A different kind of container that is Iterableimport java.util.*;public class SimpleQueue<T> implements Iterable<T> { private LinkedList<T> storage = new LinkedList<T>(); public void add(T t) { storage.offer(t); } public T get() { return storage.poll(); } public Iterator<T> iterator() { return storage.iterator(); }} // /:~
Fill2.java
Addable和生成器接口Generator,适配器模式
//: generics/Fill2.java// Using adapters to simulate latent typing.// {main: Fill2Test}import generics.coffee.*;import java.util.*;import net.mindview.util.*;import static net.mindview.util.Print.*;interface Addable<T> { void add(T t);}public class Fill2 { public static void main(String[] args) { // Adapt a Collection: List<Coffee> carrier = new ArrayList<Coffee>(); Fill2.fill(new AddableCollectionAdapter<Coffee>(carrier), Coffee.class, 3); // Helper method captures the type: Fill2.fill(Adapter.collectionAdapter(carrier), Latte.class, 2); for (Coffee c : carrier) print(c); print("----------------------"); // Use an adapted class: AddableSimpleQueue<Coffee> coffeeQueue = new AddableSimpleQueue<Coffee>(); Fill2.fill(coffeeQueue, Mocha.class, 4); Fill2.fill(coffeeQueue, Latte.class, 1); for (Coffee c : coffeeQueue) print(c); } // Classtoken version: public static <T> void fill(Addable<T> addable, Class<? extends T> classToken, int size) { for (int i = 0; i < size; i++) try { addable.add(classToken.newInstance()); } catch (Exception e) { throw new RuntimeException(e); } } // Generator version: public static <T> void fill(Addable<T> addable, Generator<T> generator, int size) { for (int i = 0; i < size; i++) addable.add(generator.next()); }}// To adapt a base type, you must use composition.// Make any Collection Addable using composition:class AddableCollectionAdapter<T> implements Addable<T> { private Collection<T> c; public AddableCollectionAdapter(Collection<T> c) { this.c = c; } public void add(T item) { c.add(item); }}// A Helper to capture the type automatically:class Adapter { public static <T> Addable<T> collectionAdapter(Collection<T> c) { return new AddableCollectionAdapter<T>(c); }}// To adapt a specific type, you can use inheritance.// Make a SimpleQueue Addable using inheritance:class AddableSimpleQueue<T> extends SimpleQueue<T> implements Addable<T> { public void add(T item) { super.add(item); }}
24 函数对象用作策略设计模式
一种优雅的设计,泛型,函数,策略的结合,适配器模式和策略模式的结合,高中自然科学中数学中的函数和泛型函数的思想联系。
//: generics/Functional.javaimport java.math.*;import java.util.concurrent.atomic.*;import java.util.*;import static net.mindview.util.Print.*;// Different types of function objects:interface Combiner<T> { T combine(T x, T y);}interface UnaryFunction<R, T> { R function(T x);}interface Collector<T> extends UnaryFunction<T, T> { T result(); // Extract result of collecting parameter}interface UnaryPredicate<T> { boolean test(T x);}public class Functional { // Calls the Combiner object on each element to combine // it with a running result, which is finally returned: public static <T> T reduce(Iterable<T> seq, Combiner<T> combiner) { Iterator<T> it = seq.iterator(); if (it.hasNext()) { T result = it.next(); while (it.hasNext()) result = combiner.combine(result, it.next()); return result; } // If seq is the empty list: return null; // Or throw exception } // Take a function object and call it on each object in // the list, ignoring the return value. The function // object may act as a collecting parameter, so it is // returned at the end. public static <T> Collector<T> forEach(Iterable<T> seq, Collector<T> func) { for (T t : seq) func.function(t); return func; } // Creates a list of results by calling a // function object for each object in the list: public static <R, T> List<R> transform(Iterable<T> seq, UnaryFunction<R, T> func) { List<R> result = new ArrayList<R>(); for (T t : seq) result.add(func.function(t)); return result; } // Applies a unary predicate to each item in a sequence, // and returns a list of items that produced "true": public static <T> List<T> filter(Iterable<T> seq, UnaryPredicate<T> pred) { List<T> result = new ArrayList<T>(); for (T t : seq) if (pred.test(t)) result.add(t); return result; } // To use the above generic methods, we need to create // function objects to adapt to our particular needs: static class IntegerAdder implements Combiner<Integer> { public Integer combine(Integer x, Integer y) { return x + y; } } static class IntegerSubtracter implements Combiner<Integer> { public Integer combine(Integer x, Integer y) { return x - y; } } static class BigDecimalAdder implements Combiner<BigDecimal> { public BigDecimal combine(BigDecimal x, BigDecimal y) { return x.add(y); } } static class BigIntegerAdder implements Combiner<BigInteger> { public BigInteger combine(BigInteger x, BigInteger y) { return x.add(y); } } static class AtomicLongAdder implements Combiner<AtomicLong> { public AtomicLong combine(AtomicLong x, AtomicLong y) { // Not clear whether this is meaningful: return new AtomicLong(x.addAndGet(y.get())); } } // We can even make a UnaryFunction with an "ulp" // (Units in the last place): // 最后一位,小时点 static class BigDecimalUlp implements UnaryFunction<BigDecimal, BigDecimal> { public BigDecimal function(BigDecimal x) { return x.ulp(); } } static class GreaterThan<T extends Comparable<T>> implements UnaryPredicate<T> { private T bound; public GreaterThan(T bound) { this.bound = bound; } public boolean test(T x) { return x.compareTo(bound) > 0; } } static class MultiplyingIntegerCollector implements Collector<Integer> { private Integer val = 1; public Integer function(Integer x) { val *= x; return val; } public Integer result() { return val; } } public static void main(String[] args) { // Generics, varargs & boxing working together: List<Integer> li = Arrays.asList(1, 2, 3, 4, 5, 6, 7); Integer result = reduce(li, new IntegerAdder()); print(result); result = reduce(li, new IntegerSubtracter()); print(result); print(filter(li, new GreaterThan<Integer>(4))); print(forEach(li, new MultiplyingIntegerCollector()).result()); print(forEach(filter(li, new GreaterThan<Integer>(4)), new MultiplyingIntegerCollector()).result()); MathContext mc = new MathContext(7); List<BigDecimal> lbd = Arrays.asList(new BigDecimal(1.1, mc), new BigDecimal(2.2, mc), new BigDecimal(3.3, mc), new BigDecimal(4.4, mc)); BigDecimal rbd = reduce(lbd, new BigDecimalAdder()); print(rbd); print(filter(lbd, new GreaterThan<BigDecimal>(new BigDecimal(3)))); // Use the prime-generation facility of BigInteger: List<BigInteger> lbi = new ArrayList<BigInteger>(); BigInteger bi = BigInteger.valueOf(11); for (int i = 0; i < 11; i++) { lbi.add(bi); bi = bi.nextProbablePrime(); } print(lbi); BigInteger rbi = reduce(lbi, new BigIntegerAdder()); print(rbi); // The sum of this list of primes is also prime: // 是否是素数 print(rbi.isProbablePrime(5)); List<AtomicLong> lal = Arrays.asList(new AtomicLong(11), new AtomicLong(47), new AtomicLong(74), new AtomicLong(133)); AtomicLong ral = reduce(lal, new AtomicLongAdder()); print(ral); print(transform(lbd, new BigDecimalUlp())); }} /* * Output: 28 -26 [5, 6, 7] 5040 210 11.000000 [3.300000, 4.400000] [11, 13, 17, * 19, 23, 29, 31, 37, 41, 43, 47] 311 true 265 [0.000001, 0.000001, 0.000001, * 0.000001] */// :~
- Thinking in java4 15章 泛型
- Thinking in java4 16章 数组
- Thinking in java4 容器
- Thinking in java4 Exception
- Thinking in java4 14章 RTT和反射学习笔记
- java线程 同步临界区:thinking in java4 21.3.5
- java线程共享受限资源 解决资源竞争 thinking in java4 21.3
- java 并发原子性与易变性 来自thinking in java4 21.3.3
- java 线程 原子类相关操作示例 thinking in java4 目录21.3.4
- java线程 在其他对象上同步、线程本地存储ThreadLocal:thinking in java4 21.3.6
- java 线程 在阻塞时终结 之中断讲解 ---thinking in java4
- 《thinking-in-java》读书笔记-第15章-泛型(一)
- Thinking in Java 第15章 泛型(15.1-15.4)
- Thinking in Java 第15章 泛型(15.5-15.19)
- thinking in java笔记 15 泛型
- Thinking in Java 泛型
- 泛型------thinking in java
- Thinking in java:泛型
- hdu 1003 MAX Sum
- 工厂方法模式实例
- MySQL锁的用法之行级锁
- JSP的三个编译指令之page
- nginx实现简单的负载均衡
- Thinking in java4 15章 泛型
- 修改win10和ubuntu双系统启动顺序
- TCP 接收连接及消息的收发
- Android M 指纹框架
- yum 出现错误ImportError: No module named urlgrabber.grabber
- 使用meshlabserver批量处理三维模型(附代码)
- 深度学习fine-tuning
- Measure
- 集合框架_泛型接口的概述和使用