资讯专栏INFORMATION COLUMN

[Java] 浅析Google Guava Multimap

yiliang / 3203人阅读

摘要:类关系实现方法是以为的特定实现,这个类中没有太多的实际代码,主要是方法中特定的产生一个作为。是的一个专有版本,这个类和接口一起,将的方法都重写为。则是所有以为核心的的基本实现,这里实现了所有的方法,是最重要的一部分。

类关系

ArrayListMultiMap.java

Multimap 
|
|
AbstractMultimap                   Serializable     
|__________________________________________|
|
AbstractMapBasedMultimap   
|
|
AbstractListMultimap               ListMultimap 
|__________________________________________|
|
ArrayListMultiMap

LinkedListMultiMap.java

Multimap 
|
|
AbstractMultimap               ListMultimap                  Serializable 
|__________________________________________|______________________________|
|
LinkedListMultimap

TreeMultimap.java

Multimap 
|
|
AbstractMultimap                   Serializable     
|__________________________________________|
|
AbstractMapBasedMultimap           SetMultimap     
|__________________________________________|
|
AbstractSetMultimap               SortedSetMultimap 
|__________________________________________|
|
AbstractSortedSetMultimap  
|
|
AbstractSortedKeySortedSetMultimap 
|
|
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 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 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 removeAll(@Nullable Object key) {
    // 先将Key移出
    Collection collection = map.remove(key);
    // 如果Value为空,则返回空集合
    if (collection == null) {
      return createUnmodifiableEmptyCollection();
    }
    // 否则将Value的值拷贝到输出集合中,再把Value清空
    Collection 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 get(@Nullable K key) {
    Collection 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 collection = asMap().get(key);
    // 如果集合不为空,则找到集合中的这个值并删除
    return collection != null && collection.remove(value);
}

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

public boolean putAll(@Nullable K key, Iterable 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 valueCollection = (Collection) values;
      // 拿出Collection然后把新的addAll进去
      return !valueCollection.isEmpty() && get(key).addAll(valueCollection);
    } else {
      Iterator valueItr = values.iterator();
      // 拿出Iterator然后把新的addAll进去
      return valueItr.hasNext() && Iterators.addAll(get(key), valueItr);
    }
}

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

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

replace方法

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

containsValue方法

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

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64679.html

相关文章

  • 浅析guava容器multimap

    摘要:它主要做了件事初始化容器,并将元素添加到容器里维护这样我们再调用的方法直接就返回了,不需要再次遍历和统计的过程。维护实时的维护,及时删除总结整体上是对底层的二次封装,很好的处理了各种细节,比如子容器的判空处理,的计算效率,的维护等。 在日常开发中我们通常有需要对 List 容器进行分组的情况,比如对下面的list数据根据name字段来进行分组: [ { date...

    yy13818512006 评论0 收藏0
  • 近几个月Github上最热门的Java项目一览

    摘要:今天逛了逛,顺手精选出了一下近几个月以来上最热门的个项目。相关阅读正式开源,帮助应用快速容器化未来可能会上热门的项目地址介绍哈哈,皮一下很开心。这是我自己开源的一份文档,目前仍在完善中,欢迎各位英雄好汉一起完善。 showImg(https://segmentfault.com/img/remote/1460000015766827?w=391&h=220);今天逛了逛Github,顺...

    cyqian 评论0 收藏0
  • 推荐10个Java方向最热门的开源项目(8月)

    摘要:设计模式可以通过提供经过验证的经过验证的开发范例来加速开发过程。将流程作为突破点,并在多个领域工作,包括流量控制,并发,断路和负载保护,以保护服务稳定性。 1. JCSprout(Java核心知识库) Github地址: https://github.com/crossoverJie/JCSprout star: 12k 介绍: 处于萌芽阶段的 Java 核心知识库。 2....

    wushuiyong 评论0 收藏0
  • eclipse collections入门

    摘要:配合一下方法使用类似的方法,用于提取一个里头的一个属性出来。当然,也可以简写为主要用来过滤集合。配合使用功能与相同,只是把该筛选条件内置在中然后这里直接使用,传入参数与功能相反集合分区只取出一个符合条件的计数与条件满足判断其他转参考 Function 配合一下方法使用: collect flatCollect groupBy minBy maxBy toSortedListBy so...

    LeexMuller 评论0 收藏0
  • Guava 源码分析(Cache 原理)

    摘要:缓存本次主要讨论缓存。清除数据时的回调通知。具体不在本次的讨论范围。应该是以下原因新起线程需要资源消耗。维护过期数据还要获取额外的锁,增加了消耗。 showImg(https://segmentfault.com/img/remote/1460000015272232); 前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛。 我平时用的也挺频繁,这次就借助日...

    wangxinarhat 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<