《Java编程思想》泛型中的策略设计模式

来源:互联网 发布:华中数据交易所 编辑:程序博客网 时间:2024/05/26 02:20

开始这一篇博客之前,我先简单解释一下什么叫做策略设计模式,举个实际的例子,老唐现在很饿想去吃点饭,我可以骑车去,那么我就需要一辆自行车,如果我要打车去,那就要有个滴滴打车的APP,如果我要坐地铁我就得拿着我的公交卡,简而言之就是为了吃饭我可以有不同的去吃饭的方式,这就是策略设计模式的概念。
下面直接上代码:

import java.math.*;import java.util.concurrent.atomic.*;import java.util.*;import static net.mindview.util.Print.*;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();}interface UnaryPredicate<T>//返回boolean类型的参数{    boolean test(T x);}public class Functional{    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;        }        //如果seq是个空序列,那么只能返回空对象        return null;    }    public static <T> Collector<T> forEach(Iterable<T> seq,Collector<T> func){        for(T t : seq){            func.function(t);        }        return func;    }    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;    }    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;    }    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){            return new AtomicLong(x.addAndGet(y.get()));        }    }    static class BigDecimalUlp implements UnaryFunction<BigDecimal,BigDecimal>{        public BigDecimal function(BigDecimal x){            //以0.xx1的格式返回数字的精度            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){        List<Integer> li = Arrays.asList(1,2,3,4,5,6,7);        Integer result = reduce(li, new IntegerAdder());        //reduce将li中的数字通过IntegerAdder类中的combine方法相加        print(result);//输出:28        result = reduce(li, new IntegerSubtracter());        //方法同上面,只不过将加法变成了减法        print(result);//输出-26        print(filter(li, new GreaterThan<Integer>(4)));        //输出[5, 6, 7],filter也是调用了GreaterThan中的.test()函数,对数字进行了比较        print(forEach(li,                new MultiplyingIntegerCollector()).result());        //输出5040,forEach()调用了MultiplyingIntegerCollector中的function方法,将所有元素相乘        print(forEach(filter(li, new GreaterThan<Integer>(4)),                new MultiplyingIntegerCollector()).result());        //输出210,先使用filter方法调用了Greater中的.test方法将1,2,3,4排除,然后只剩下了        //5,6,7,随后又调用forEach方法将5,6,7,相乘得到210        MathContext mc = new MathContext(7);        //MathContext用于设置小数的精度        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());        //reduce调用了new BigDecimalAdder()对象中的.combine()方法将数字相加        print(rbd);        //输出11.000000        print(filter(lbd,                new GreaterThan<BigDecimal>(new BigDecimal(3))));        //输出:[3.300000, 4.400000],filter方法调用GreaterThan中的.test,把所有大于3的数全部保留下来        List<BigInteger> lbi = new ArrayList<BigInteger>();        BigInteger bi = BigInteger.valueOf(11);        for(int i=0; i<11; i++){            lbi.add(bi);            bi = bi.nextProbablePrime();            //nextProbablePrime的用法是返回一个大于bi的素数整数        }        print(lbi);        //输出:[11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]        BigInteger rbi = reduce(lbi, new BigIntegerAdder());        print(rbi);        //输出:311        print(rbi.isProbablePrime(5));        //输出:true,这个数是一个素数,其参数的意思是可以接受判断出错的程度        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);        //输出:265        //AtomicXXX都是指的线程安全的类        print(transform(lbd, new BigDecimalUlp()));        //输出:[0.000001, 0.000001, 0.000001, 0.000001]        //transform调用BigDecimalUlp中的.function()方法,返回了数字的精度    }}

注意:IntegerAdder和BigDecimalAdder调用了不同的方法,但是都解决了相同的问题,就是两个数相加,这是适配器模式和策略模式的结合。

原创粉丝点击