Thinking in java4 15章 泛型

Thinking in java4 15章 泛型

1 生成器的妙用

2 Set2的集合,操作。

//: net/mindview/util/Sets.java
package 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.java

public 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.java
import 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.java
import 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 Iterable
import 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.java
import 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值