当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

[Java] 浅析Google Guava Multimap

作者:小梦 来源: 网络 时间: 2024-01-14 阅读:

类关系

ArrayListMultiMap.java

Multimap <I>||AbstractMultimap <A>      Serializable <I>    |__________________________________________||AbstractMapBasedMultimap <A>  ||AbstractListMultimap <A>  ListMultimap <I>|__________________________________________||ArrayListMultiMap

LinkedListMultiMap.java

Multimap <I>||AbstractMultimap <A>  ListMultimap <I>     Serializable <I>|__________________________________________|______________________________||LinkedListMultimap

TreeMultimap.java

Multimap <I>||AbstractMultimap <A>      Serializable <I>    |__________________________________________||AbstractMapBasedMultimap <A>          SetMultimap <I>    |__________________________________________||AbstractSetMultimap <A>  SortedSetMultimap <I>|__________________________________________||AbstractSortedSetMultimap <A> ||AbstractSortedKeySortedSetMultimap <A>||TreeMultimap

实现方法

ArrayListMultimap

ArrayListMultiMap.java是以ArrayList为Collection的特定实现,这个类中没有太多的实际代码,主要是createCollection()方法中特定的产生一个ArrayList作为Collection。

AbstractListMultimap.java是AbstractMultimap的一个List专有版本,这个类和ListMultimap接口一起,将Multimap的方法都重写为List。

AbstractMapBasedMultimap.java则是所有以Map为核心的Multimap的基本实现,这里实现了所有Multimap的方法,是最重要的一部分。

clear方法,先将每个collection清空,再把map清空

public void clear() {    // Clear each collection, to make previously returned collections empty.    for (Collection<V> collection : map.values()) {      collection.clear();    }    map.clear();    totalSize = 0;}

put方法,我们可以发现这里的size是每多一个KV对就加1,而不是唯一Key的数量,这点和Map不同

public boolean put(@Nullable K key, @Nullable V value) {    Collection<V> collection = map.get(key);    // 如果这是一个新key没有对应的Collection    if (collection == null) {      // 先根据子类实现创建一个相应的Collection      collection = createCollection(key);      // 将KV对加入Map中      if (collection.add(value)) {        totalSize++;        map.put(key, collection);        return true;      } else {        throw new AssertionError("New Collection violated the Collection spec");      }    // 如果已经有这个key了,就加入它的Collection    } else if (collection.add(value)) {      totalSize++;      return true;    } else {      return false;    }}

removeAll方法,需要返回删除的Value,所以要一个临时变量存起来

public Collection<V> removeAll(@Nullable Object key) {    // 先将Key移出    Collection<V> collection = map.remove(key);    // 如果Value为空,则返回空集合    if (collection == null) {      return createUnmodifiableEmptyCollection();    }    // 否则将Value的值拷贝到输出集合中,再把Value清空    Collection<V> output = createCollection();    output.addAll(collection);    totalSize -= collection.size();    collection.clear();    // 返回输出集合    return unmodifiableCollectionSubclass(output);}

size方法,注意这里返回的是KV数,而非K的唯一个数

public int size() {    return totalSize;}

isEmpty方法,判断KV数是否为0

public boolean isEmpty() {    return size() == 0;}

get方法

public Collection<V> get(@Nullable K key) {    Collection<V> collection = map.get(key);    // 如果没有Value就新建一个Collection    if (collection == null) {      collection = createCollection(key);    }    return wrapCollection(key, collection);}    

AbstractMultimap.java也实现了一些基本方法,和上一个文件一起涵盖了所有API

remove方法

public boolean remove(@Nullable Object key, @Nullable Object value) {    // 从Map中按照key找到该集合    Collection<V> collection = asMap().get(key);    // 如果集合不为空,则找到集合中的这个值并删除    return collection != null && collection.remove(value);}

putAll方法,以key为第一参数,以一个Iterable为第二参数

public boolean putAll(@Nullable K key, Iterable<? extends V> values) {    checkNotNull(values);    // make sure we only call values.iterator() once    // and we only call get(key) if values is nonempty    if (values instanceof Collection) {      Collection<? extends V> valueCollection = (Collection<? extends V>) values;      // 拿出Collection然后把新的addAll进去      return !valueCollection.isEmpty() && get(key).addAll(valueCollection);    } else {      Iterator<? extends V> valueItr = values.iterator();      // 拿出Iterator然后把新的addAll进去      return valueItr.hasNext() && Iterators.addAll(get(key), valueItr);    }}

putAll方法,以另一个Multimap为参数

public boolean putAll(Multimap<? extends K, ? extends V> multimap) {    boolean changed = false;    for (Map.Entry<? extends K, ? extends V> entry : multimap.entries()) {      changed |= put(entry.getKey(), entry.getValue());    }    return changed;}

replace方法

public Collection<V> replaceValues(@Nullable K key, Iterable<? extends V> values) {    checkNotNull(values);    // 先移除所有    Collection<V> result = removeAll(key);    // 在加入新的值    putAll(key, values);    return result;}

containsValue方法

public boolean containsValue(@Nullable Object value) {    // 检查每一个Collection是否有这个值    for (Collection<V> collection : asMap().values()) {      if (collection.contains(value)) {        return true;      }    }    return false;}

containsEntry方法,实际上是用get来判断是否有这个key,然后再看是否有这个值

public boolean containsEntry(@Nullable Object key, @Nullable Object value) {    Collection<V> collection = asMap().get(key);    return collection != null && collection.contains(value);}

热点阅读

网友最爱