Java集合之Map容器

Map的值的存储方式与Collection的存储方式稍有不同,Map中是键值对存储,键唯一,值可以重复。Map的实现类有HashMap、WeakHashMap、Hashtable和TreeMap。本篇文章介绍除HashMap外的Map,由于HashMap的内容较多,因此将其单独放在这篇文章

Map

Map与Collection无关,他们的存储值的方式也完全不同,只是在实现某些数据结构的时候可能会互相依赖。主要方法如下:

//键值对数量
int size();
//键值对数量是否为0
boolean isEmpty();
//是否包含指定键
boolean containsKey(Object key)
//是否包含指定值
boolean containsValue(Object value)
//根据键获取值
V get(Object key)
//向Map中添加键值对并返回值
V put(K key,V value)
//通过键删除键值对并返回值
V remove(Object key)
//清空Map
void clear();
//返回所有的键,存储在Set中
Set<K> keySet();
//返回所有的值,存储在Collection<V>中
Collection<V> values();
//内部接口,Map依靠此接口实现键值对存储
interface Entry<K,V> {
    //获取键
    K getKey();
    //获取值
    V getValue();
    //设置值
    V setValue(V value);
}

AbstractMap

在讨论Map的具体实现类之前,我们先讨论一下AbstractMap类,这个类的作用提供Map中一些方法的通用实现,是所有Map的父类。

//键值对的个数
public int size(){
    return entrySet().size();
}
//返回Entry<K,V>的Set表示,由子类实现
public abstract Set<Entry<K,V>> entrySet();
//是否为空Map
public boolean isEmpty(){
    return size() == 0;
}
//Map中是否包含指定的Value,这个方法与Collection中的实现一样,当然其实就是Set的方法,只不过封装的是Entry<K,V>
public boolean containsValue(Object value){
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if(value == null){
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(e.getValue() == null){
                return true;
            }
        }
    } else {
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(value.equals(e.getValue())){
                return true;
            }
        }
    }
    return false;
}
//Map中是否包含指定的key,与containsValue()方法实现完全相同
public boolean containsKey(Object key){
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if(key== null){
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(e.getKey() == null){
                return true;
            }
        }
    } else {
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(key.equals(e.getKey())){
                return true;
            }
        }
    }
    return false;
}
//通过指定的key返回对应的value,没有则返回null。此方法与containsKey()类似,只是返回值不同
public V get(Object key){
    Iterator<Entry<K,V>> i = entrySet().iterator();
    if(key== null){
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(e.getKey() == null){
                return e.getValue();
            }
        }
    } else {
        while(i.hasNext()){
            Entry<K,V> e = i.next();
            if(key.equals(e.getKey())){
                return e.getValue();
            }
        }
    }
    return null;
}
//通过指定的key删除键值对并返回旧值
public V remove(Object key){
    Iterator<Entry<K,V>> i = entrySet().iterator();
    Entry<K,V> correctEntry = null;
    if(key == null){
        while(correctEntry == null || i.hasNext()){
            Entry<K,V> e = i.next();
            if(e.getKey() == null){
                correctEntry = e;
            }
        }
    } else {
        while(correctEntry == null || i.hasNext()){
            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;
}
//返回key的Set集合,keySet为AbstractMap中的属性,子类如果没有定义keySet的值,此方法用匿名内部类定义了AbstractSet的子类和Iterator的实现类来自定义对key的遍历。
public Set<K> keySet(){
    Set<K> ks = keySet;
    if(ks == null){
        ks = new AbstractSet<K>(){
            public Iterator<K> iterator(){
                return new Iterator<K>(){
                    private Iterator<K> i = entrySet().iterator();
                    public boolean hasNext(){
                        return i.hasNext();
                    }
                    public K next(){
                        return i.next().getKey();
                    }
                    public void remove(){
                        return i.remove();
                    }
                };
            }
            public int size(){
                return AbstractMap.this.size();
            }
            public boolean isEmpty(){
                return AbstractMap.this.isEmpty();
            }
            public void clear(){
                AbstractMap.this.clear();
            }
            public boolean contains(Object key){
                return AbstractMap.this.containsKey(key);
            }
        };
        keySet = ks;
    }
    return ks;
}
//返回value的Collection集合,values为AbstractMap类的属性,与keySet作用相同,实现方式也相同
public Collection<V> values(){
    collection<V> vals = values;
    if(vals == null){
        vals = new Collection<V>(){
            public Iterator<V> iterator(){
                return new Iterator<V>(){
                    private Iterator<V> i = entrySet().iterator();
                    public boolean hasNext(){
                        return i.hasNext();
                    }
                    public V next(){
                        return i.next().getValue();
                    }
                    public void remove(){
                        return i.remove();
                    }
                };
            }
            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);
            }
        };
        values = vals;
    }
    return vals;
}

TreeMap

TreeMap是一个有序的键值对集合,基于红黑树实现,

WeakHashMap

WeakHashMap相比于其他的Map实现类较少用甚至较少见到,WeakHashMap的特点是键是弱引用。

HashTable

HashTable与HashMap功能和结构类似,但也有一些区别,如下:

  • HashTable是线程安全的,它的的方法都使用了synchronized修饰;HashMap不是线程安全的。
  • HashTable的键和值都不能为null;HashMap键和值都可以是null,且值可以有多个null。
  • HashTable继承的是Dictionary类(已过时),HashMap继承的是AbstractMap类。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值