前言
离HashMap又进了一步
AbstractMap提供了对Map接口的骨架实现,以减少实现Map接口所做出的努力。
还是架构图,这Map接口有大体的了解,方便翻看
AbstractMap文档
要实现一个不更改的map,编程人员只需要继承此类并提供对entrySet方法的实现(返回映射的映射关系的set视图)。通常,返回的set将依次在AbstractSet上实现。此Set就该不支持add或remove方法,并且共迭代器应不支持remove方法
要实现一个可更改的map,编程人员必须额外的重写此类的put方法(否则将抛出一个UnsupportedOperationException),并且entrySet().iterator()应该额外实现其remove方法
编程人员应提供一个无参和一个带有map类型参数的构造器,按照Map接口规范中的建议
源码
public abstract class AbstractMap<K, V> implements Map<K, V>{
public AbstractMap() {
}
public int size(){
return entrySet().size();
}
public boolean
isEmpty(){
return size() ==
0;
}
public boolean
containsValue(Object
value){
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
if(
value ==
null){
while (i.hasNext()){
Map.Entry<K, V> e = i.next();
if(e.getValue() ==
null){
return true;
}
}
}
else{
while(i.hasNext()){
Map.Entry<K, V> e = i.next();
if (
value.equals(e.getValue())) {
return true;
}
}
}
return false;
}
public boolean
containsKey(Object key){
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
if (key ==
null) {
while (i.hasNext()) {
Map.Entry<K, V> e = i.next();
if (e.getValue() ==
null) {
return true;
}
}
}
else {
while (i.hasNext()) {
Map.Entry<K, V> e = i.next();
if (key.equals(e.getKey())) {
return true;
}
}
}
return false;
}
public V
get(Object key) {
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
if(key ==
null){
while (i.hasNext()) {
Map.Entry<K, V> e = i.next();
if(e.getKey() ==
null){
return e.getValue();
}
}
}
else {
while (i.hasNext()){
Map.Entry<K, V> e = i.next();
if (key.equals(e.getKey())) {
return e.getValue();
}
}
}
return null;
}
public V
put(K key, V
value){
throw new UnsupportedOperationException();
}
public V
remove(Object key){
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
Map.Entry<K, V> correctEntry =
null;
if(key ==
null){
while (correctEntry ==
null && i.hasNext()){
Map.Entry<K, V> e = i.next();
if(e.getKey() ==
null){
correctEntry = e;
}
}
}
else{
while (correctEntry ==
null && i.hasNext()){
Map.Entry<K, V> e = i.next();
if (key.equals(e.getKey())) {
correctEntry = e;
}
}
}
V oldValue =
null;
if(correctEntry !=
null){
oldValue = correctEntry.getValue();
i.remove();
}
return oldValue;
}
public void putAll(Map<? extends K, ? extends V> m){
for(Map.Entry<? extends K, ? extends V> e : m.entrySet()){
put(e.getKey(), e.getValue());
}
}
public void clear(){
entrySet().clear();
}
public abstract Set<Map.Entry<K, V>>
entrySet();
transient Set<K> keySet;
transient Collection<V> values;
public Set<K>
keySet(){
Set<K> ks = keySet;
if(ks ==
null){
ks =
new AbstractSet<K>() {
@Override
public Iterator<K>
iterator() {
return new Iterator<K>() {
private Iterator<Map.Entry<K, V>> i = entrySet().iterator();
@Override
public boolean
hasNext() {
return i.hasNext();
}
@Override
public K
next() {
return i.next().getKey();
}
public void remove(){
i.remove();
}
};
}
@Override
public int size() {
return AbstractMap.
this.size();
}
public boolean
isEmpty(){
return AbstractMap.
this.isEmpty();
}
public void clear(){
AbstractMap.
this.clear();
}
public boolean
contains(Object k){
return AbstractMap.
this.containsKey(k);
}
};
keySet = ks;
}
return ks;
}
public Collection<V>
values(){
if (values ==
null) {
values =
new AbstractCollection<V>() {
@Override
public Iterator<V>
iterator() {
return new Iterator<V>() {
private Iterator<Map.Entry<K, V>> i = entrySet().iterator();
@Override
public boolean
hasNext() {
return i.hasNext();
}
@Override
public V
next() {
return i.next().getValue();
}
public void remove() {
i.remove();
}
};
}
@Override
public int size() {
return AbstractMap.
this.size();
}
public boolean
isEmpty(){
return AbstractMap.
this.isEmpty();
}
public void clear(){
AbstractMap.
this.clear();
}
public boolean
contains(Object v){
return AbstractMap.
this.containsValue(v);
}
};
}
return values;
}
public boolean
equals(Object o){
if (o ==
this) {
return true;
}
if (!(o instanceof Map)) {
return false;
}
Map<?, ?> m = (Map<?, ?>) o;
try {
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
while (i.hasNext()) {
Map.Entry<K, V> e = i.next();
V
value = e.getValue();
K key = e.getKey();
if (
value ==
null) {
if (!(m.
get(key) ==
null && m.containsKey(key))) {
return false;
}
}
else {
if (
value.equals(m.
get(key))) {
return false;
}
}
}
}
catch (ClassCastException unused) {
return false;
}
catch (NullPointerException unused) {
return false;
}
return true;
}
public int hashCode(){
int h =
0;
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
while (i.hasNext()){
h += i.next().hashCode();
}
return h;
}
public String
toString(){
Iterator<Map.Entry<K, V>> i = entrySet().iterator();
if(!i.hasNext()) {
return "{}";
}
StringBuilder sb =
new StringBuilder();
sb.append(
'{');
for(;;){
Map.Entry<K, V> e = i.next();
V
value = e.getValue();
K key = e.getKey();
sb.append(key ==
this ?
"(this Map)" : key);
sb.append(
value ==
this ?
"(this Map)" :
value);
if(!i.hasNext()){
return sb.append(
'}').toString();
}
sb.append(
',').append(
' ');
}
}
private static boolean
eq(Object o1, Object o){
return o1 ==
null ? o ==
null : o1.equals(o);
}
public static class SimpleEntry<K, V>
implements Map.Entry<K, V>, Serializable{
private static final
long serialVersionUID = -
849971149061103585L;
private final K key;
private V
value;
public SimpleEntry(K key, V
value) {
this.key = key;
this.
value =
value;
}
public SimpleEntry(Map.Entry<? extends K, ? extends V> entry){
this.key = entry.getKey();
this.
value = entry.getValue();
}
@Override
public K
getKey() {
return key;
}
@Override
public V
getValue() {
return value;
}
@Override
public V
setValue(V
value) {
V oldValue =
this.
value;
this.
value =
value;
return oldValue;
}
public boolean
equals(Object o){
if(!(o instanceof Map.Entry)){
return false;
}
Map.Entry<? , ?> e = (Map.Entry<?, ?>) o;
return eq(key, e.getKey()) && eq(
value, e.getValue());
}
public int hashCode(){
return (key ==
null ?
0 : key.hashCode()) ^
(
value ==
null ?
0 :
value.hashCode());
}
public String
toString(){
return key +
"=" +
value;
}
}
public static class SimpleImmutableEntry<K, V>
implements Map.Entry<K, V>, Serializable{
private static final
long serialVersionUID =
713839143949025153L;
private final K key;
private final V
value;
public SimpleImmutableEntry(K key, V
value) {
this.key = key;
this.
value =
value;
}
public SimpleImmutableEntry(Map.Entry<? extends K, ? extends V> entry){
this.key = entry.getKey();
this.
value = entry.getValue();
}
@Override
public K
getKey() {
return key;
}
@Override
public V
getValue() {
return value;
}
@Override
public V
setValue(V
value) {
throw new UnsupportedOperationException();
}
public boolean
equals(Object o){
if (!(o instanceof Map.Entry)) {
return false;
}
Map.Entry<?, ?> e = (Map.Entry<?, ?>) o;
return eq(key, e.getKey()) && eq(
value, e.getValue());
}
public int hashCode(){
return (key ==
null ?
0 : key.hashCode()) ^
(
value ==
null ?
0 :
value.hashCode());
}
public String
toString(){
return key +
"=" +
value;
}
}
}
参考
JDK1.8 AbstractMap