【问题标题】:Google guava vs Scala collection framework comparisonGoogle guava vs Scala 集合框架对比
【发布时间】:2011-07-06 14:57:45
【问题描述】:

有很多常见的概念:

  • 不可变集合,
  • 集合视图,
  • 严格/非严格收集,
  • 集合建设者

Guava 和 Scala Collection API 中的模式相同。 那么区别是什么呢?两个库都符合模式吗?扩展的容易性是否足够好?

所以我想听听使用它们的人对这些框架的比较。

【问题讨论】:

  • 好问题!两者都贴近我的心。

标签: java scala guava scala-collections


【解决方案1】:

Google Guava 是一个很棒的库,这是毫无疑问的。但是,它是用 Java 实现的,并且受到所有限制:

  • 标准库中没有不可变集合接口
  • 没有 lambda 字面量(闭包),因此围绕 SAM 类型需要一些繁重的样板文件,例如谓词
  • 类型规范有很多重复,尤其是涉及泛型的地方

Guava 也必须存在于 Java 的标准集合库中,因此很少有 3rd 方库会公开与 guava 兼容的函数字面量或使用特定于 guava 的集合类型。这会导致您使用的每个第三方库的阻抗不匹配。例如,您通常希望将从此类库返回的集合转换为适当的 guava 不可变集合 - 特别是在多线程环境中工作时。

Scala 集合具有更好地集成到语言中的设计,您会发现它们在整个 scala 标准库中以及通过 Scala 中实现的 3rd 方产品广泛使用。默认情况下,Scala 集合也是不可变的,因此您最终会得到更安全的代码,不需要额外的防御性包装层。

如果您可以使用 Scala,那么就这样做吧,它除了集合框架之外还有很多优势。如果您必须使用 Java,那么 Guava 是一个不错的选择,尤其是考虑到 Scala 集合如果没有 Scala 提供的语言特性就不是特别容易使用。

在混合项目中,Guava 集合完全可以在 Scala 中使用,但该语言还提供了允许您使用 Java 集合(包括公开相同接口的 Guava)的机制,就好像它们是 Scala 自己的集合一样。

【讨论】:

  • +1 "标准库中没有不可变集合接口。" Guava 必须实现可变接口并在可变方法上返回异常,从而导致可能的运行时异常......呃
  • +1 我认为您发现了最大的不同之一。在运行时检查 Guava 的不变性,而在编译时检查 Scala 的不变性。
  • 您为什么认为第三方库如此反对在其 API 中使用(非测试版)Guava 类型?考虑到 Guava 对向后兼容性的严格要求,有什么缺点?
  • 这是一个旧线程,但应该补充一点,随着 java 8 的新“功能”特性,许多 Guava 方法将被这些方法所取代。谷歌的人都知道这一点,尽管我不知道他们整合两者的策略是什么。
  • @Jas - Table 看起来非常像带有元组作为键的 Map,尽管我可以理解为什么需要它,因为 Java 缺少元组。至于Multiset; Scala 只有一个可变版本,很多人批评了这个事实。
【解决方案2】:

我现在在我所有的 java 项目中都使用番石榴。它为具有相似模式的 java 集合提供了很好的功能性。

然而,用java编写闭包意味着直接定义大量匿名类,既冗长又乏味。

Scala 集合在设计(由于特征的部分实现的级联)和功能方面仍然优越。只需实现一小部分方法,即可轻松创建自己的集合并获得 scala 集合的所有优势。

【讨论】:

    【解决方案3】:

    其他人已经回答了您的问题,但我认为您错过了一个有趣的替代方案,Functional Java 库。它忽略 Java 集合 API,并提供外观和行为类似于简化的 Scala 集合的不可变集合。

    【讨论】:

      【解决方案4】:

      我使用过 Scala、Google 集合和 F#。最近我一直在使用 Google 集合迭代器,并忽略了 F# 序列表达式的强大功能。似乎 Scala 更喜欢非严格(惰性)列表而不是迭代器/序列。

      在 F# 和 Google 集合(请参阅 google Iterators)中,您可以转换和过滤迭代器,创建一个很好的工作推送管道,表示为对象流。并不是说你不能在 Scala 中做到这一点,它只是不常见。 F# 有一个很酷的管道运算符,用于过滤迭代器(序列)。

      例如,我希望 Scala 的 yield 表达式生成一个类似于 Python(或 F# 序列块)的迭代器,而不是返回一个列表。

      两者非常相似,Scala 在速度和语法方面具有巨大优势,但在使用它们时我觉得(我的看法):

      • Google 集合专注于 Map 和 Iterator。
      • Scala 非常注重列表。

      请注意,Scala 2.8 似乎对其集合进行了一些重大更改(我使用的是旧版本的 Scala)。

      【讨论】:

      • Scala 列表是严格的,惰性列表是流。在我看来,过滤器在 Scala 中也很常见,但隐藏在 for-expression 守卫中。是你的意思吗?
      • @paradigmatic 是的,这就是我的意思。大多数语言区分列表、惰性列表和流/迭代器。 Scala 和 Haskell 有时会模糊界限。这很好,只是我不熟悉。
      • for-comprehensions 尝试返回您放入的集合类型。在迭代器上使用它们通常会返回过滤/映射的迭代器。
      • “大变化”是轻描淡写。 Scala 2.8 集合从头开始重写。它们是完全不同的野兽,并且更加更强大、更灵活。
      • @Adam:请不要删除您的帖子。该对话框对我们这些从 Scala 开始的人很有帮助。
      猜你喜欢
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      • 1970-01-01
      • 2010-11-29
      • 1970-01-01
      • 2013-10-10
      • 2015-06-02
      • 1970-01-01
      相关资源
      最近更新 更多