Java集合(3):使用Abstract类
每个java.util容器都有其自己的Abstract类,它们提供了该容器接口的部分实现。下面是一个定制自己的Map的例子(List set就省略了):
定制自己的Map实现AbstractMap-->Map,需要实现[Set<Map.Entry<K,V>> entrySet()]方法
实现[Set<Map.Entry<K,V>> entrySet()]方法分两步:
(1) 实现Set<E>接口
(2) 实现Map.Entry<K,V>接口
1 import java.util.AbstractMap; 2 import java.util.AbstractSet; 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 import java.util.HashSet; 6 import java.util.Hashtable; 7 import java.util.Iterator; 8 import java.util.LinkedHashMap; 9 import java.util.LinkedHashSet; 10 import java.util.LinkedList; 11 import java.util.List; 12 import java.util.Map; 13 import java.util.Set; 14 import java.util.TreeMap; 15 import java.util.TreeSet; 16 17 class Countries { 18 public static final String[][] DATA = { 19 // Africa 20 { "SOUTH AFRICA", "Cape Town" }, { "SUDAN", "Khartoum" }, 21 // Asia 22 { "CHINA", "Beijing" }, { "JAPAN", "Tokyo" }, { "SOUTH KOREA", "Seoul" }, 23 // Australia and Oceania 24 { "AUSTRALIA", "Canberra" }, { "NEW ZEALAND", "Wellington" }, 25 // Europe 26 { "UNITED KINGDOM", "London" }, { "FRANCE", "Paris" }, { "GERMANY", "Berlin" }, { "ITALY", "Rome" }, 27 { "SPAIN", "Madrid" }, 28 // North and Central America 29 { "UNITED STATES OF AMERICA", "Washington, D.C." }, { "CANADA", "Ottawa" }, 30 // South America 31 { "BRAZIL", "Brasilia" }, { "ARGENTINA", "Buenos Aires" } }; 32 33 private static class FlyweightMap extends AbstractMap<String, String> { 34 35 private final int dataLength; 36 37 private static Set<Map.Entry<String, String>> entries = new EntrySet(DATA.length); 38 39 public FlyweightMap() { 40 dataLength = 0; 41 } 42 43 public FlyweightMap(int dataLength) { 44 this.dataLength = dataLength; 45 } 46 47 @Override 48 public Set<Map.Entry<String, String>> entrySet() { 49 if (dataLength > 0) { 50 return new EntrySet(dataLength); 51 } 52 return entries; 53 } 54 55 // (1) 实现Set<E>接口 56 // 定制自己的Set实现AbstractSet(AbstractCollection)-->Set, 需要实现[Iterator<E> iterator() & int size()]方法 57 private static class EntrySet extends AbstractSet<Map.Entry<String, String>> { 58 private int size; 59 60 EntrySet(int size) { 61 this.size = size < 0 ? (this.size = 0) 62 : (size > DATA.length ? (this.size = DATA.length) : (this.size = size)); 63 } 64 65 @Override 66 public int size() { 67 return size; 68 } 69 70 @Override 71 public Iterator<Map.Entry<String, String>> iterator() { 72 return new Iterator<Map.Entry<String, String>>() { 73 // Only one Entry object per Iterator: 74 private Entry entry = new Entry(-1); 75 76 @Override 77 public boolean hasNext() { 78 return entry.index < size - 1; 79 } 80 81 @Override 82 public java.util.Map.Entry<String, String> next() { 83 entry.index++; 84 return entry; 85 } 86 }; 87 } 88 } 89 90 // (2) 实现Map.Entry<K,V>接口 91 // 定制自己的Map.Entry实现Map.Entry<K, V>接口, 需要实现下面的方法 92 // 每个Map.Entry对象都只存了它们的索引,而不是实际的键值。当调用getKey(), getValue()时,才会用索引返回恰当的元素 93 private static class Entry implements Map.Entry<String, String> { 94 int index; 95 96 Entry(int index) { 97 this.index = index; 98 } 99 100 @Override 101 public boolean equals(Object o) { 102 return DATA[index][0].equals(o); 103 } 104 105 @Override 106 public String getKey() { 107 return DATA[index][0]; 108 } 109 110 @Override 111 public String getValue() { 112 return DATA[index][1]; 113 } 114 115 @Override 116 public String setValue(String value) { 117 throw new UnsupportedOperationException(); 118 } 119 120 @Override 121 public int hashCode() { 122 return DATA[index][0].hashCode(); 123 } 124 } 125 } 126 127 // 取Map全部内容 128 public static Map<String, String> capitals() { 129 return selectAll(); 130 } 131 132 // 取Map全部内容的key 133 public static List<String> names() { 134 return new ArrayList<String>(capitals().keySet()); 135 } 136 137 // 取Map部分内容 138 public static Map<String, String> capitals(final int size) { 139 return select(size); 140 } 141 142 // 取Map部分内容的key 143 public static List<String> names(int size) { 144 return new ArrayList<String>(select(size).keySet()); 145 } 146 147 private static Map<String, String> selectAll() { 148 return new FlyweightMap(); 149 } 150 151 private static Map<String, String> select(final int size) { 152 return new FlyweightMap(size); 153 } 154 } 155 156 public class Test4 { 157 public static void main(String[] args) { 158 System.out.println(Countries.capitals(5)); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing, JAPAN=Tokyo, SOUTH KOREA=Seoul} 159 System.out.println(Countries.names(5)); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN, SOUTH KOREA] 160 System.out.println(new HashMap<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, CHINA=Beijing, SOUTH AFRICA=Cape Town} 161 System.out.println(new LinkedHashMap<String, String>(Countries.capitals(3))); // {SOUTH AFRICA=Cape Town, SUDAN=Khartoum, CHINA=Beijing} 162 System.out.println(new TreeMap<String, String>(Countries.capitals(3))); // {CHINA=Beijing, SOUTH AFRICA=Pretoria/Cape Town, SUDAN=Khartoum} 163 System.out.println(new Hashtable<String, String>(Countries.capitals(3))); // {SUDAN=Khartoum, SOUTH AFRICA=Pretoria/Cape Town, CHINA=Beijing} 164 System.out.println(new HashSet<String>(Countries.names(4))); // [SUDAN, CHINA, SOUTH AFRICA, JAPAN] 165 System.out.println(new LinkedHashSet<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN] 166 System.out.println(new TreeSet<String>(Countries.names(4))); // [CHINA, JAPAN, SOUTH AFRICA, SUDAN] 167 System.out.println(new ArrayList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN] 168 System.out.println(new LinkedList<String>(Countries.names(4))); // [SOUTH AFRICA, SUDAN, CHINA, JAPAN] 169 System.out.println(Countries.capitals().get("BRAZIL")); // Brasilia 170 } 171 }