Guava库:它最有用和/或隐藏的功能是什么?

131

我快速浏览了Guava API和它提供的新的集合类型(MultimapBiMap看起来很有用),我正在考虑将该库包含在我工作的项目中。

然而,如果这些库没有太大的好处并且学习它们的特性浪费宝贵的时间,我也会有所保留,不随意包含库。

你是否在你的项目中包含了 Guava 库,并且它是否以任何出人意料的方式证明了其有用性?你将来是否总是会使用它?它的主要优势/节省时间是什么?它有哪些隐藏的功能?


4
你的标题和问题实际上并不匹配。 - aioobe
4
“the new collection types... appear useful”可以翻译成“新的集合类型似乎很有用”。“I have a reticence to include libraries ... if they are of no great benefit”的意思是“如果库没有太大好处,我不愿意将其包含”,其中reticence指的是犹豫或不愿意。最后一句话中的“which is it then? you either think the library is useful and has benefit or you don't”可以翻译成“那到底是哪种情况?你要么认为这个库有用且有益,要么就不这么认为”。 - matt b
1
截至2017年(问题现已关闭),如果您正在使用最新的Gradle(4.4.1),则默认情况下将guava 21.0添加到build.gradle作为依赖项,并带有“此依赖项在内部使用,不会暴露给消费者自己的编译类路径”的字样,表明Gradle团队已经决定其中有一些非常有价值的东西。 - mike rodent
8个回答

159

说实话,Guava里的每个功能都很有用。我一直在使用它,仍然总能发现一些新的功能,而且它的代码行数比手动编写的代码要少。

以下是其他人没有提到的一些我喜欢的功能:

  • Multimap真的很棒。任何时候你需要使用类似于Map<Foo, Collection<Bar>>这样的结构时,可以使用Multimap代替,这样就不用繁琐地检查是否存在与键映射的集合,如果不存在则创建并添加了。
  • Ordering非常适用于构建按你想要的方式排序的Comparator
  • Maps.uniqueIndexMultimaps.index: 这些方法接受一个Iterable和一个Function,并构建一个ImmutableMapImmutableListMultimap,根据将函数应用于每个值的结果将值索引到Iterable中。因此,通过一个检索项目ID的功能,您可以在一行内按其ID索引项目列表。
  • 它提供的函数式编程工具... filter, transform, 等等。尽管使用类作为FunctionPredicate有点冗长,但我发现这很有用。在这里我举了一个使其阅读起来舒适的例子。
  • ComparisonChain是一个容易被忽视的小类,当你想编写一个比较方法以按顺序比较多个值并在找到第一个差异时返回时非常有用。它消除了所有的繁琐,只需要使用几行链式方法调用即可完成。
  • Objects.equal(Object,Object) - 安全的空指针比较。
  • Objects.hashCode(Object...) - 根据类中多个字段轻松获取哈希码的方法。
  • Objects.firstNonNull(Object,Object) - 如果第一个值为null,该方法可以简化获取默认值的代码,特别是如果第一个值是方法调用的结果(在使用常规方法之前必须将其分配给变量)。
  • CharMatcher已经被提到过了,但它们非常强大。
  • Throwables让您可以对throwable做一些很好的事情,例如Throwables.propagate,如果它是RuntimeExceptionError则重新抛出throwable,并在其他情况下将其包装在RuntimeException中并抛出。
  • 我当然可以继续说下去,但我得去工作了。=)无论如何,尽管我在这里列出了一些我喜欢的东西,但事实是Guava中的每个东西在某些情况下都很有用。其中很多东西非常常用。随着您的使用,您会发现更多的用途。不使用它会感觉像是手脚被绑起来了一样。


    2
    完全同意ComparisionChain - whiskeysierra

    45

    我在谷歌公司内已经使用Guava有数年之久了,使用效果非常出色。

    我特别喜欢以下这些部分:

    • Charsets.* - 如此简单,如此有用
    • Collections - 集合操作
    • IO处理(例如一行代码读取完整的资源等)
    • Splitter/Joiner - 字符串拆分和拼接
    • Preconditions - 先决条件检查

    6
    请注意,Java 7+中现在已经有了StandardCharsets。我想知道Guava的多少其他功能已经被纳入Java。 - DavidS
    2
    我发现了这个Modernizer Maven Plugin,它可以检测使用遗留API的情况,包括像Guava这样的第三方库。配置文件中似乎包含了67个Guava废弃警告,其中包括StandardCharsets。 - DavidS

    28

    我最初使用它是为了集合的简写。例如,不用:

    Map<String, Map<Long, List<String>>> map = new HashMap<String, Map<Long, List<String>>>();
    

    你可以这样做:

    Map<String, Map<Long, List<String>>> map = Maps.newHashMap();
    

    填充地图也很容易:

    ImmutableMap<String,String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
    

    现在,我已经发现了Guava中的其他一些有用的工具。例如,CharMatcher类允许您匹配字符序列。您可以执行以下操作:

    CharMatcher.inRange('a','z').or(inRange('A','Z'));
    
    或者
    String phoneNumber = CharMatcher.DIGIT.retainFrom("my phone number is 123456789");
    

    21

    CharMatcher的precomputed()方法源代码)是我几天前偶然发现的一个很好的“隐藏特性”。

    实际上,这只是一种优化方式,它创建了一个查找表(使用位数组),然后简单地查找字符以查看它们是否“匹配”。

    这是你在使用库时可以利用的一种隐藏优化,而在自己的代码中可能没有考虑过。

    当然,如果您创建了一个复杂的CharMatcher,并且计划多次使用它,则必须记住调用precomputed()方法,例如:

    CharMatcher complexMatcher = CharMatcher.anyOf("cat")
                                            .or(CharMatcher.DIGIT)
                                            .or(CharMatcher.WHITESPACE)
                                            .precomputed();
    

    我还有关于Guava ListenableFuture的问题。如果可能的话,您能否检查我的设计并帮助我澄清一些疑惑以及如何处理它们?我最近开始使用Guava ListenableFuture,我很喜欢它,但对如何高效使用它们有些困惑。 - john

    17
    这是一段关于编程的内容,下面是需要翻译的文本:

    这是一段来自谷歌(演讲者:Kevin Bourrillion,谷歌核心Java库的首席工程师)的YouTube视频,展示了Google Collections的美妙之处。我认为谷歌所做的一件聪明的事情是在集合中保证不可变性。


    12

    Google Guava是一个实用库,所以我怀疑里面没有杀手级别的类。关于实用工具的全部内容是几乎每个项目都会用到的。我记不得我的任何一个项目没有使用Java集合。而事实上,Google Guava的集合实用程序非常出色,应该在Java SDK本身中包含。

    我已经写了三篇关于Google Guava类的文章:

    这还不是全部,你可以用Guava做很多其他事情。


    8

    非常非常有用。几乎每个新项目都会首先添加它。

    1. 我们非常喜欢迭代器/可迭代对象和函数接口。
    2. 服务接口族是很好的抽象。
    3. 我们非常致力于使用ImmutableXXX类来表示API类型不可更改。
    4. 计算映射(来自MapMaker)在某些情况下非常棒。

    总体而言,这个库的质量非常高。API经过深思熟虑,实现也很稳定。强烈推荐。


    7

    MapMaker 现在提供了有界的 LRU 缓存 - 在一个微小的 API 背后隐藏着一些重要的机制。这对于实用性有着巨大的潜力,我还在继续研究它的代码。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接