【问题标题】:Functional Data Structures in JavaJava 中的函数式数据结构
【发布时间】:2010-12-13 14:18:21
【问题描述】:

Java 标准库是否有任何功能性数据结构,如不可变 Sets、Lists 等,具有功能更新?

【问题讨论】:

  • 您想要列表中所有对象的深层副本,还是只是提供一个新的指针列表的函数,这些指针都指向与源相同的对象?
  • 我想要一个不以愚蠢方式实现的 Set 的持久数据结构。例如,一个不可变列表可以通过将所有元素复制到一个新列表中并添加元素来实现添加 - O(n)。或者它可以是一个链表,将元素添加到头部,然后返回头部 - O(1)
  • 在 Java 中没有“深拷贝”任何东西的通用方法。

标签: java functional-programming set immutability


【解决方案1】:

我知道这是一个老问题,但稍微搜索一下告诉我,现在我们有了函数式 Java 的替代方案。

JavasLang 看起来像是一个有趣的库,用于 Java 中的声明式编程和函数式数据结构。

我没有在易用性和性能方面将它与函数式 Java 进行比较,但我很想在这方面得到任何指示。

【讨论】:

    【解决方案2】:

    字符串和数字在功能上是不可变的,但大多数集合不是(不可变集合在添加、删除等时抛出异常)。 CopyOnWriteArrayListCopyOnWriteArraySet 在这个意义上是最接近的。

    【讨论】:

      【解决方案3】:

      看看pcollections 项目:

      PCollections 充当 Java 集合框架的持久且不可变的类似物。这包括高效、线程安全、通用、不可变和持久的堆栈、映射、向量、集合和包,与它们的 Java 集合对应物兼容。

      持久性和不可变数据类型越来越多地被认为是可变数据类型的简单、设计友好、并发友好,有时更节省时间和空间的替代方案。

      【讨论】:

        【解决方案4】:

        如果您对函数式风格的集合操作感兴趣,请查看lambdaj

        【讨论】:

          【解决方案5】:

          很高兴看到 Google Collections 被插入,但不,我们没有这个。我不知道有任何 Java 库可以做到。在 Google 内部,我们实现了一些功能性的 List 结构,你猜怎么着?没有人使用它们。所以它们不太可能很快成为开源的。

          【讨论】:

            【解决方案6】:

            Functional javaSets, Lists 和更多有趣的抽象。

            【讨论】:

              【解决方案7】:

              你不需要斯卡拉。只需将您的收藏传递到:

              java.util.Collections.unmodifiableCollection(/* Collection<? extends T> c */);
              java.util.Collections.unmodifiableSet(Set s);
              java.util.Collections.unmodifiableMap(Map m);
              java.util.Collections.unmodifiableList(List l);
              

              我刚刚从另一个 SO 问题中看到了这一点:

              Google 的 ImmutableSet

              http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html

              来自文档:

              不像 Collections.unmodifiableSet(java.util.Set), 这是一个单独的视图 仍然可以改变的收藏,一个 此类的实例包含其 拥有私人数据,永远不会 改变。这门课很方便 公共静态最终集(“常量 集”),还可以让您轻松制作 提供给的一套“防御性副本” 来电者的课程。

              经过编辑以纳入评论。

              【讨论】:

              • +1: 你更快了 =) 顺便还有unmodifiableList(), unmodifiableMap(), 还有更多方法可以在java.util.Collections API: java.sun.com/javase/6/docs/api/java/util/Collections.html
              • 我想在 Set 中添加一些东西,保持旧 Set 不变,并返回一个新 Set。我不认为 unmodifiableSet 给了我这个?
              • @Claudiu 是的,unmodifiableSet 肯定不会那样做。
              • 不可变和不可修改不是一回事。尝试改变不可修改的集合将导致 RuntimeException,而对于不可变集合,这种突变根本不可能,因此保证代码不会在运行时崩溃。 (如果你不明白我的意思,请查看fj.data.List的源代码。)
              【解决方案8】:

              【讨论】:

                【解决方案9】:

                嗯,“改变”不可变集合有两种可能的方法:

                • 制作包含“更改”的副本

                • 创建一个新的、不同的对象,其中包含对原始对象的引用和对更改描述的引用。

                Clojure 采用后一种方法,因此可以相当快地创建原始集合的许多同级,并对每个同级进行少量更正,并具有合理的内存需求。但大多数 Java 代码倾向于选择第一种。

                不管怎样,Google 已经创建了一些支持函数式编程的集合:http://code.google.com/p/google-collections/,但我没有深入研究它们。

                【讨论】:

                  【解决方案10】:

                  听起来您正在寻找Scala。它编译为 .class,这样就足够了,对吧?

                  【讨论】:

                  • 嗯也许。只是我们在功能性课程中获得了一些支持代码(即向结构添加一些内容会返回一个带有更新的新版本),但它是通过始终复制旧结构并向其添加新内容来编写的。这让我悲伤。我想知道是否有一种简单、更好的方法,但我猜 Java 只会让它变得困难。
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-11-15
                  • 1970-01-01
                  • 2011-03-19
                  • 2011-05-19
                  • 1970-01-01
                  • 2023-04-02
                  • 2011-12-16
                  相关资源
                  最近更新 更多