package com.dhh.MapTest; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class Countries { //基本数据 public static final String[][] DATA={ {"1","1A"},{"2","2A"},{"4","4A"},{"5","5A"},{"6","6A"},{"7","7A"}, {"8","8A"},{"9","9A"},{"0","0A"},{"11","11A"},{"12","12A"},{"13","13A"}, {"14","14A"},{"15","15A"},{"16","16A"},{"17","17A"},{"18","18A"},{"19","19A"} }; //内部类一个Map容器 private static class FlyWeightMap extends AbstractMap<String,String>{ //内部类的内部类一个Entry容器代表二维数组中的某个kv private static class Entry implements Map.Entry<String, String>{ int index; Entry(int index){ this.index=index; } @Override public String getKey() { return DATA[index][0]; } @Override public String getValue() { // TODO Auto-generated method stub return DATA[index][1]; } @Override public String setValue(String value) { // TODO Auto-generated method stub throw new UnsupportedOperationException(); } public boolean equals(Object o) { return DATA[index][0].equals(o); } public int hashCode(){ return DATA[index][0].hashCode(); } } //内部类中另外一个内部类,一个set容器 static class EntrySet extends AbstractSet<Map.Entry<String, String>>{ //尺寸 private int size; //构造器定义set的大小 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 this.size; } //set的迭代器里面有之前的标记当前键值对的Entry private class Iter implements Iterator<Map.Entry<String, String>>{ private Entry entry=new Entry(-1); @Override public boolean hasNext() { // TODO Auto-generated method stub return entry.index<size-1; } @Override public java.util.Map.Entry<String, String> next() { entry.index++; return entry; } public void remove(){ throw new UnsupportedOperationException(); } } @Override public Iterator<java.util.Map.Entry<String, String>> iterator() { // TODO Auto-generated method stub return new Iter(); } } //静态创建一个满容器的EntrySet private static Set<java.util.Map.Entry<String, String>> entries=new EntrySet(DATA.length); //返回一个满容器的EntrySet @Override public Set<java.util.Map.Entry<String, String>> entrySet() { // TODO Auto-generated method stub return entries; } } //创建一个非默认尺寸的FlyWeightMap 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<>(map.keySet()); public static List<String> names(){ return names; } public static List<String> names(int size){ return new ArrayList<String>(select(size).keySet()); } }
享元模式“
如果发现某个对象的生成了大量细粒度的实例,并且这些实例除了几个参数外基本是相同的,如果把那些共享参数移到类外面,在方法调用时将他们传递进来,就可以通过共享大幅度单个实例的数目。
如上代码所示,所有信息储存在某个二维数组当中,只有调用时才抽取其中的信息。无论多少次创建该对象,都只有一个静态的DATA二位数组。实际上我们创建的Map对象只是一系列方法,并不占用存储空间。
它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。