guava guide阅读 2020-02-22

https://github.com/google/guava/wiki/NewCollectionTypesExplained
guava 对jdk原生的Collection类型进行了扩充;


允许存在重复元素/Key的Set or Map

  • 提供了相应允许重复的版本名为Multixxx, 如 MultiSet, MultiMap(特意提到并不是只是接口很像,但是并不是基于Map or Set的实现); 并提供两种视图,一种是转成List, 另一种是转成Map<K, Collection<V>>类型; 的确是很有用的,可能作用到的场景;
    • 元素统计;
    • 分组, Collection.groupby;
    • 有些场景,我是想将原始Map的key 和 value对调的, MultiMap就可以做到;

BitMap 一种可以方便交换Key Value的Map

  • 上面刚提到想要交换Key, Value,这里就提供了专属的Map;再很多场景下,我们的Map希望存储的是PAIR的概念,key 和 value 分别并不是那么明显,都有可能要作为检索的关键字; 刚好可以使用BitMap;
  • 从文档描述来看, BitMap 只能处理 key 和 value是一一对应的case;

RangSet 该Set的元素是一个Range<T extend Comparable>, 它可以实现对期间进行拆分,合并等功能

  • 此前因为工作需要(开发一个划分按照日期划分收租的系统),写过类似的功能; 但是当时并没有进一步想过去推广到所有实现了Comparable的Type;
    简单测试了一下可用, 不过仍然存在几点问题;
    • 我们可以把这个RangeSet理解为一个集合的概念, 那么就又交集,并集等操作,可以发现Range.class里的确有相关操作(intercourse, span...etc)
    • 我们日常对日期的划分,往往是需要按照给定一个期间,按照年份,月份,季度 or 其他因素进行划分; 所以这个API在具体场景下, 是有进一步封装的必要;
           RangeSet<Date> rangeSet = TreeRangeSet.create();
           rangeSet.add(Range.closed(DateUtil.str2Date("2019-01-31"), DateUtil.str2Date("2019-02-27")));
           rangeSet.add(Range.closed(DateUtil.str2Date("2019-01-31"), DateUtil.str2Date("2019-02-27")));
           rangeSet.add(Range.openClosed(DateUtil.str2Date("2019-03-31"), DateUtil.str2Date("2019-04-27")));
           rangeSet.add(Range.closed(DateUtil.str2Date("2019-05-01"), DateUtil.str2Date("2019-08-27")));
           rangeSet.remove(Range.closed(DateUtil.str2Date("2019-06-01"), DateUtil.str2Date("2019-06-30")));
           rangeSet.asRanges().forEach(a -> {
               System.out.println(String.format("Date Period %s%s to %s%s", a.lowerBoundType() == BoundType.CLOSED ? "[" : "(", DateUtil.date2Str(a.lowerEndpoint())
                       , DateUtil.date2Str(a.upperEndpoint()), a.upperBoundType() == BoundType.CLOSED ? "]" : ")"));
           });
//输出的结果
Date Period [2019-01-31 to 2019-02-27]
Date Period (2019-03-31 to 2019-04-27]
Date Period [2019-05-01 to 2019-06-01)
Date Period (2019-06-30 to 2019-08-27]


guava集合工具集说明
https://github.com/google/guava/wiki/CollectionUtilitiesExplained


  • 工具命名都是后面加S(除Collection 命名为Collections); 就如java nio File->Files, Path -> paths;
    以后做工具,也按照这个规范命名好了;


    image.png
  • 类似于Arrays.asList,不过它返回的是可以可以进行添加删除操作的List; Arrays.asList是个比较坑的设计,见过不少人出过错;以后可以使用Lists.newArrayList避免出错,并且可以帮忙初始化List容量;
List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");
  • 一般而言我们对性能没这种偏执的要求,但是知道一下;
List<Type> exactly100 = Lists.newArrayListWithCapacity(100);
List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);
Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);

看了一眼源码,设计者还没具体描述他预估容量算法的依据;


image.png
  • Iterables
    • 在Iterables工具中并没法什么对我有价值的功能,都是很基础的功能(这些功能很基础,但是还是很有价值的,比如可以把一个文件流像集合类一样操作,只是一般不需要);而且我个人更偏向于自己实现内部迭代;

Whenever possible, Guava prefers to provide utilities accepting an Iterable rather than a Collection. Here at Google, it's not out of the ordinary to encounter a "collection" that isn't actually stored in main memory, but is being gathered from a database, or from another data center, and can't support operations like size() without actually grabbing all of the elements.
对这句话倒是很有感触, 不仅仅要面向抽象/接口编程,而且要尽可能的面向更底层的抽象和接口编程;这一方面增加了对设计者抽象能力的要求,还免不了拆分/细分工作;因为有迭代器的并不仅仅Collection;希望guava可以切实做到这点,这样我的一些其他类可以使用它的方法了;

  • Sets 提供了一些基础的集合操作;这个自己也曾经实现过; 结合Range.class,有Range.class和集合互相转化的方法吗?

  • Maps

    • 下面这个方法应该有用,它接受的是个Iterable, 可以很方便的将一个可遍历的Object转成Map;
    //public static <K,V> ImmutableMap<K,V> uniqueIndex(Iterable<V> values, Function<? super V,K> 
    keyFunction)
    ImmutableMap<Integer, String> stringsByIndex = Maps.uniqueIndex(strings, new Function<String, 
    Integer> () {
    public Integer apply(String string) {
       return string.length();
     }
    });
    
  • Multimaps

    • invertFrom K,V调换Multimaps版本;有用;
    ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
    multimap.putAll("b", Ints.asList(2, 4, 6));
    multimap.putAll("a", Ints.asList(4, 2, 1));
    multimap.putAll("c", Ints.asList(2, 5, 3));
    
    TreeMultimap<Integer, String> inverse = Multimaps.invertFrom(multimap, TreeMultimap.<String, Integer> 
    create());
    // note that we choose the implementation, so if we use a TreeMultimap, we get results in order
    /*
    * inverse maps:
    *  1 => {"a"}
    *  2 => {"a", "b", "c"}
    *  3 => {"c"}
    *  4 => {"a", "b"}
    *  5 => {"c"}
    *  6 => {"b"}
    */
    
    • forMap 将普通的Map 转成MultiMap(如前所述,Multimap的实现与java原生的Map是完全不同的),然后使用Multimap的一些功能;
    Map<String, Integer> map = ImmutableMap.of("a", 1, "b", 1, "c", 2);
    SetMultimap<String, Integer> multimap = Multimaps.forMap(map);
    // multimap maps ["a" => {1}, "b" => {1}, "c" => {2}]
    Multimap<Integer, String> inverse = Multimaps.invertFrom(multimap, HashMultimap.<Integer, String> 
    create());
    // inverse maps [1 => {"a", "b"}, 2 => {"c"}]
    
  • Wraps

    • 一个集合的设计方法规范;如果设计一个A(必须是个一个接口), 那么提供了3个版本;普通实现版本, 不可变版本(Unmodifiable),应对并发版本(Synchronized), 以及一个factory 让用户可以选择自定义A的实现细节,如下;
    ListMultimap<String, Integer> myMultimap = Multimaps.newListMultimap(
    Maps.<String, Collection<Integer>>newTreeMap(),
    new Supplier<LinkedList<Integer>>() {
      public LinkedList<Integer> get() {
        return Lists.newLinkedList();
      }
    });
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,273评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,349评论 3 398
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,709评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,520评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,515评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,158评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,755评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,660评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,203评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,287评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,427评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,122评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,801评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,272评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,393评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,808评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,440评论 2 359

推荐阅读更多精彩内容