java填充容器的几种方法

1.使用Generator填充Collection

首先定义一个Generator的接口

public interface Generator<T> {
    T next();
}

用适配器模式将Generator适配到Collection的构造器上,这个类使用Generator在容器中放置所需数量的对象,然后所产生的容器可以传递给任何Collection的构造器。

public class CollectionData<T> extends ArrayList<T>{
    public CollectionData(Generator<T> gen, int quantity){
        for (int i = 0; i < quantity; i++){
            add(gen.next());
        }
    }
    public static <T> CollectionData<T> list(Generator<T> gen, int quantity){
        return new CollectionData<T>(gen, quantity);
    }
}

测试,addAll()方法是所有Collection子类型的一部分,用来组装现有的Collection。

class Goverment implements Generator{

    String[] foundation = ("strange women lying in ponds distributing swords" +
            " is no basis for a system of government").split(" ");
    private int index;
    @Override
    public Object next() {
        return foundation[index++];
    }
}
public class CollectionDataTest {

    public static void main(String[] args) {
        //构造器填充
        Set<String> set = new LinkedHashSet<String>(new CollectionData<String>(new Goverment(), 15));
        System.out.println(set);
        //list填充
        set.addAll(CollectionData.list(new Goverment(), 15));
        System.out.println(set);
    }
}

2.Map生成器

首先定义一个Pair类,因为为了组装Map,每次调用Generator的next()方法都必须产生一个“对象对”。key和value域都是public和final,为了使Pair成为只读的数据传输对象。

public class Pair<K,V> {
    public final K key;
    public final V value;
    public Pair(K k, V v){
        this.key = k;
        this.value = v;
    }
}

Map适配器

public class MapData<K,V> extends LinkedHashMap<K,V> {
    //参数为一个单独的pair的构造器
    public MapData(Generator<Pair<K,V>> gen, int quantity){
        for (int i = 0; i < quantity; i++){
            Pair<K,V> p = gen.next();
            put(p.key,p.value);
        }
    }
    //参数为两个不同Generator对象的构造器
    public MapData(Generator<K> genK, Generator<V> genV, int quantity){
        for (int i = 0; i < quantity; i++){
            put(genK.next(), genV.next());
        }
    }
    //key一个为Generator对象,value为普通对象的构造器
    public MapData(Generator<K> genK, V value, int quantity){
        for (int i = 0; i < quantity; i++){
            put(genK.next(), value);
        }
    }
    //key为迭代器对象,value为Generator对象
    public MapData(Iterable<K> genK, Generator<V> genV){
        for (K key : genK){
            put(key, genV.next());
        }
    }
    //key为迭代器对象,value为普通对象
    public MapData(Iterable<K> genK, V value){
        for (K key : genK){
            put(key, value);
        }
    }

    //对应的静态方法
    public static <K,V> MapData<K,V> map(Generator<Pair<K,V>> gen, int quantity){
        return new MapData<K, V>(gen,quantity);
    }
    public static <K,V> MapData<K,V> map(Generator<K> genK, Generator<V> genV, int quantity){
        return new MapData<K, V>(genK,genV, quantity);
    }
    public static <K,V> MapData<K,V> map(Generator<K> genK, V value, int quantity){
        return new MapData<K, V>(genK, value, quantity);
    }
    public static <K,V> MapData<K,V> map(Iterable<K> genK, Generator<V> genV){
        return new MapData<K, V>(genK, genV);
    }
    public static <K,V> MapData<K,V> map(Iterable<K> genK, V value){
        return new MapData<K, V>(genK, value);
    }
}

测试类

class Letters implements Generator<Pair<Integer,String>>,Iterable<Integer>{

    private int size = 9;
    private int number = 1;
    private char letter = 'A';

    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            @Override
            public boolean hasNext() {
                return number < size;
            }

            @Override
            public Integer next() {
                return number++;
            }

            public void remove(){
                throw new UnsupportedOperationException();
            }
        };
    }

    @Override
    public Pair<Integer, String> next() {
        return new Pair<Integer,String>(number++,"" + letter++);
    }
}
public class MapDataTest {
    public static void main(String[] args) {
        // Pair Generator
        System.out.println(MapData.map(new Letters(), 11));
        //Two separate generators
        System.out.println(MapData.map(new CountingGenerator.Character(),
                new RandomGenerator.String(3), 8));
        //a key Generator and a single value
        System.out.println(MapData.map(new CountingGenerator.Character(), "Value", 6));
        //An Iterable and a value Generator
        System.out.println(MapData.map(new Letters(), new RandomGenerator.String(3)));
        //An Iterable and a single value
        System.out.println(MapData.map(new Letters(), "Pop"));
    }
}
public class CountingGenerator {
    public static class Boolean implements Generator<java.lang.Boolean>{
        private boolean value = false;
        public java.lang.Boolean next(){
            value = !value;
            return value;
        }
    }
    public static class Byte implements Generator<java.lang.Byte>{
        private byte value = 0;
        public java.lang.Byte next(){
            return value++;
        }
    }
    static char[] chars = ("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();
    public static class Character implements Generator<java.lang.Character>{
        int index = -1;
        public java.lang.Character next(){
            index = (index + 1) % chars.length;
            return chars[index];
        }
    }
    public static class String implements Generator<java.lang.String>{
        private int length = 7;
        Generator<java.lang.Character> cg = new Character();
        public String(){}
        public String(int length){
            this.length = length;
        }
        public java.lang.String next(){
            char[] buf = new char[length];
            for (int i = 0; i < length; i++){
                buf[i] = cg.next();
            }
            return new java.lang.String(buf);
        }
        public static class Short implements Generator<java.lang.Short>{
            private short value = 0;
            public java.lang.Short next(){
                return value++;
            }
        }
        public static class Integer implements Generator<java.lang.Integer>{
            private int value = 0;
            public java.lang.Integer next(){
                return value++;
            }
        }
        public static class Long implements Generator<java.lang.Long>{
            private long value = 0;
            public java.lang.Long next(){
                return value++;
            }
        }
        public static class Float implements Generator<java.lang.Float>{
            private float value = 0;
            public java.lang.Float next(){
                float result = value;
                value += 1.0;
                return result;
            }
        }
        public static class Double implements Generator<java.lang.Double>{
            private double value = 0;
            public java.lang.Double next(){
                double result = value;
                value += 1.0;
                return result;
            }
        }
    }
}
public class RandomGenerator {
    private static Random r= new Random(47);
    public static class Boolean implements Generator<java.lang.Boolean>{
        public java.lang.Boolean next(){
            return r.nextBoolean();
        }
    }
    public static class Byte implements Generator<java.lang.Byte>{
        public java.lang.Byte next(){
            return (byte)r.nextInt();
        }
    }
    public static class Character implements Generator<java.lang.Character>{
        public java.lang.Character next(){
            return CountingGenerator.chars[r.nextInt(CountingGenerator.chars.length)];
        }
    }
    public static class String extends CountingGenerator.String{
        {cg = new Character();}
        public String(){}
        public String(int length){super(length);}
    }
    public static class Integer implements Generator<java.lang.Integer>{
        private int mod = 10000;
        public Integer(){}
        public Integer(int modulo){mod = modulo;}
        public java.lang.Integer next(){
            return r.nextInt();
        }
    }
    public static class Short implements Generator<java.lang.Short>{
        public java.lang.Short next(){
            return (short)r.nextInt();
        }
    }
    public static class Long implements Generator<java.lang.Long>{
        private int mod = 10000;
        public Long(){}
        public Long(int module){mod = module;}
        public java.lang.Long next(){
            return new java.lang.Long(r.nextInt(mod));
        }
    }
    public static class Float implements Generator<java.lang.Float>{
        public java.lang.Float next(){
            //Math.round():四舍五入
            int trimmed = Math.round(r.nextFloat() * 100);
            return ((float)trimmed) / 100;
        }
    }
    public static class Double implements Generator<java.lang.Double>{
        public java.lang.Double next(){
            long trimmed = Math.round(r.nextDouble() * 100);
            return ((double)trimmed) / 100;
        }
    }
}

3.使用Abstract类

享元模式:可以在普通的解决方案需要过多的对象,或者产生普通对象太多时使用享元。享元模式使得对象的一部分可以被具体化,因此,与对象中的所有事物都包含在对象内部不同,我们可以在更加高效的外部表中查找对象的一部分或整体。
下面的实例通过继承java.util.Abstract来创建定制的MapCollection。为了创建只读的Map,可以继承AbstractMap并实现entrySet()。为了创建只读的Set,可以继承AbstractSet并实现iterator()和size()。

public class Countries {
    public static final String[][] DATA = {
            {"ALGERIA","Algiers"}, {"ANGOLA","Luanda"}, {"BENIN","Porto-Novo"},
            {"BOTSWANA","Gaberone"}, {"BURKINA FASO", "Ouagadoudou"}
    };
    //use AbstractMap by implementing entrySet()
    private static class FlyweightMap extends AbstractMap<String,String>{
        //Entry:Map中的一个对象,只存储对象的索引
        private static class Entry implements Map.Entry<String,String>{
            int index;
            Entry(int index){ this.index = index; }
            public boolean equals(Object o){
                return DATA[index][0].equals(o);
            }
            public String getKey() { return DATA[index][0]; }
            public String getValue() { return DATA[index][1]; }
            public String setValue(String value) {
                throw new UnsupportedOperationException();
            }
            public int hashCode(){
                return DATA[index][0].hashCode();
            }
        }
        //Use AbstractSet by implementing size() & iterator
        //Map对象的集合
        static class EntrySet extends AbstractSet<Map.Entry<String,String>>{
            private int size;
            EntrySet(int size){
                if (size < 0)
                    this.size = 0;
                else if (size > DATA.length)
                    this.size = DATA.length;
                else
                    this.size = size;
            }
            public int size() { return size; }
            //迭代Entry对象,迭代器只存储对象的索引
            private class Iter implements Iterator<Map.Entry<String,String>>{
                //Only one Entry object per Iterator
                private Entry entry = new Entry(-1);
                public boolean hasNext(){
                    return entry.index < size - 1;
                }
                public Map.Entry<String,String> next(){
                    entry.index++;
                    return entry;
                }
                public void remove(){
                    throw new UnsupportedOperationException();
                }
            }
            public Iterator<Map.Entry<String,String>> iterator(){
                return new Iter();
            }
        }
        private static Set<Map.Entry<String,String>> entries = new EntrySet(DATA.length);
        public Set<Map.Entry<String,String>> entrySet(){
            return entries;
        }
        //Create a partial(局部的) map of 'size' countries
        static Map<String,String> select(final int size){
            return new FlyweightMap(){
                public Set<Map.Entry<String,String>> entrySet(){
                    return new EntrySet(size);
                }
            };
        }
        static Map<String,String> map = new FlyweightMap();
        public static Map<String,String> capitals(){
            return map;
        }
        public static Map<String,String> capitals(int size){
            return select(size);
        }
        static List<String> names= new ArrayList<String>(map.keySet());
        public static List<String> names() { return names; }
        public static List<String> names(int size){
            return new ArrayList<String>(select(size).keySet());
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值