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] */// :~
0 0
原创粉丝点击