容器的深入研究
一、容器的填充
①、使用Collections类的nCopies()与fill()方法
②、创建Generator类填充容器
③、由于Map不属于Collection,创建Map的Generator填充容器
④、复习Map的遍历
⑤、Map及享元模式。
回答:
1、Collections.nCopies():输入对象及生成对象的数量,返回List;
public static void main(String[]args){ List list = Collections.nCopies(new String("Hello"),5); List newList = new ArrayList(list); }
Collections.fill():输入Collection对象,及需要填充的对象,替换掉所有List内部已存在的对象
public static void main(String[] args){ //使用Collections.nCopies()填充List List list = new ArrayList(Collections.nCopies(new String("asd"),5)); System.out.println(list.toString()); //使用Collections.fill()置换对象 Collections.fill(list,new String("hellow")); System.out.println(list.toString()); } /*输出: *[asd, asd, asd, asd, asd] *[hellow, hellow, hellow, hellow, hellow] */
2、创建Generator类填充容器
任务:填充Arrylist容器
步骤1、创建Generator接口 2、创建接口的实现类 3、创建CollectionData类继承ArrayList类
public interface Generator<T> { T next(); }
public class IntegerGenerator implements Generator<Integer>{ private Random random = new Random(); @Override public Integer next() { // TODO Auto-generated method stub return random.nextInt(100); } }
public class CollectionData<T> extends ArrayList<T> { public CollectionData(Generator<T> generator,int count){ //填充容器 for(int i=0; i<count; ++i){ add(generator.next()); } } //静态方法构造容器 public static <E>CollectionData<E> list(Generator<E> generator,int count){ return new CollectionData<>(generator, count); } }
public class Main { public static void main(String[] args) { // TODO Auto-generated method stub //通过CollectionData创建 List<Integer> list = new CollectionData<Integer>(new IntegerGenerator(), 10); System.out.println(list.toString()); //两种创建容器的方法 list = CollectionData.list(new IntegerGenerator(), 5); System.out.println(list.toString()); } }
3、创建Generator填充Map
步骤1、创建信使类Pair(存储 map的key 和 value) 2、创建Generator(前面构造过了不在赘述) 3、创造PairGenerator类实现Generator接口 4、创建MapData类
发现:步骤和容器的填充其实是一致的,只不过是map需要key和value所以就建立一个信使类来封装
public class MapData<K,V> extends HashMap<K,V>{ public MapData(Generator<Pair<K,V>> generator,int count){ //跟之前ArrayList的容器填充,是一样的方法 for(int i=0; i<count; ++i){ Pair<K,V> pair = generator.next(); put(pair.key, pair.value); } } public static <K,V>MapData<K, V> getMap(Generator<Pair<K, V>> generator,int count){ return new MapData<>(generator, count); } }
4、Map的遍历方式(借用3、生成的map)
①、遍历Key ②、遍历Value ③、遍历key和value的组合Entry
public class Main { public static void main(String[]args){ HashMap<Integer, String> map = CollectionMap.getMap(new PairGenerator(), 8); System.out.println(map.toString()); //获取key的遍历器 Set<Integer> mapKey = map.keySet(); for(Integer key: mapKey){ System.out.print(key+" "); } //获取value的遍历器 Collection<String> mapValue = map.values(); for(String value : mapValue){ System.out.print(value+" "); } //获取map的key与value的组合(Entry) Set<Entry<Integer, String>> data = map.entrySet(); for(Map.Entry<Integer, String> mapData: data){ System.out.print(mapData.getKey()+" value"+mapData.getValue()+" "); } } }
5、Map与享元模式
需求:有一组关于国家与首都的数据
例:String[][] str = {{Chian,BeiJing},{USA,NewYork}...};
但是不想一个一个的加入map中去。有什么办法能够解决。
①、享元模式是什么
http://www.cnblogs.com/chenssy/p/3330555.html
步骤:1、创建享元类的超类接口(文章中是Shape) 2、创建享元类(同时要分清除哪些是外部需改变的成员变量,哪些是内部无需改变的成员变量) 3、创建享元工厂(最重要的是HashMap 如果外部状态相同,则不创建,如果外部状态不相同则创建)
②、如何解决不加入到map直接使用str中的数据。(自定义map,将map获取数据的位置,转移到str)
步骤1、继承AbstractMap类,重写entrySet()方法 2、创建Set继承EntrySet ->创建Entry类继承Entry 3、使用
解析:通过修改map内部的entry来修改map获取数据的来源。
①、继承AbstractMap类
public class CountryMap extends AbstractMap<String, String>{ //初始数据 private String str[][] = { {"China","BeiJing"}, {"American","NewYork"}, {"British","Landon"} }; @Override public Set<Entry<String, String>> entrySet() { // TODO Auto-generated method stub return null; } }
②、创建CountrySet类继承AbstractSet 前需要创建CountryEntry类继承Entry 因为Set存储的是Entry。
/* * 1、继承Entry接口 * 2、创建索引变量,因为是entry通过索引来获取数组中的数据。也就是通过修改index来获取数组中的变量。这样可以不用多次创建Entry给Set,从而实现了享元模式(index作为外部状态)。 * 3、实现方法 */ class CountEntry implements Entry<String,String>{ public int index = -1; @Override public String getKey() { // TODO Auto-generated method stub return str[index][0]; } @Override public String getValue() { // TODO Auto-generated method stub return str[index][1]; } //设置为只读,无法修改 @Override public String setValue(String value) { // TODO Auto-generated method stub try { throw new Exception(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
/** *1、继承AbstractSet接口,将泛型设置为Entry<String,String> *2、创建Iterator迭代器。 */ class CountrySet extends AbstractSet<Entry<String, String>>{ private CountEntry entry = new CountEntry(); @Override public Iterator<Entry<String, String>> iterator() { // TODO Auto-generated method stub return new Iterator<Entry<String, String>>() { @Override public boolean hasNext() { // TODO Auto-generated method stub entry.index += 1; if (entry.index >= str.length){ return false; } else { return true; } } @Override public Entry<String, String> next() { // TODO Auto-generated method stub return entry; } }; } @Override public int size() { // TODO Auto-generated method stub return str.length; } }
完整代码:(该Map为只读模式)
public class CountryMap extends AbstractMap<String, String>{ private String str[][] = { {"China","BeiJing"}, {"American","NewYork"}, {"British","Landon"} }; class CountEntry implements Entry<String,String>{ public int index = -1; @Override public String getKey() { // TODO Auto-generated method stub return str[index][0]; } @Override public String getValue() { // TODO Auto-generated method stub return str[index][1]; } @Override public String setValue(String value) { // TODO Auto-generated method stub try { throw new Exception(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } class CountrySet extends AbstractSet<Entry<String, String>>{ private CountEntry entry = new CountEntry(); @Override public Iterator<Entry<String, String>> iterator() { // TODO Auto-generated method stub return new Iterator<Entry<String, String>>() { @Override public boolean hasNext() { // TODO Auto-generated method stub entry.index += 1; if (entry.index >= str.length){ return false; } else { return true; } } @Override public Entry<String, String> next() { // TODO Auto-generated method stub return entry; } }; } @Override public int size() { // TODO Auto-generated method stub return str.length; } } @Override public Set<Entry<String, String>> entrySet() { // TODO Auto-generated method stub return new CountrySet(); } }