通过持久性集合,我的意思是像clojure中的集合。
例如,我有一个包含元素(a,b,c)的列表。 使用普通列表,如果我添加d,我的原始列表将包含(a,b,c,d)作为其元素。 使用持久列表,当我调用list.add(d)时,我返回一个新列表,持有(a,b,c,d)。 但是,实现尝试尽可能在列表之间共享元素,因此它比仅返回原始列表的副本更具内存效率。 它还具有不可变的优点(如果我持有对原始列表的引用,那么它将始终返回原始的3个元素。)
这在其他地方解释得更好(例如http://en.wikipedia.org/wiki/Persistent_data_structure)。
无论如何,我的问题是......在java中提供此功能的最佳库是什么?我可以以某种方式使用clojure集合(其他通过直接使用clojure)?
答案 0 :(得分:16)
直接使用Clojure中的内容。显然你可能不想使用它自己的语言,你仍然可以直接使用持久集合,因为它们都只是Java类。
import clojure.lang.PersistentHashMap;
import clojure.lang.IPersistentMap;
IPersistentMap map = PersistentHashMap.create("key1", "value1");
assert map.get("key1").equals("value1");
IPersistentMap map2 = map.assoc("key1", "value1");
assert map2 != map;
assert map2.get("key1").equals("value1");
(免责声明:我实际上没有编译该代码:)
缺点是集合没有输入,即没有泛型。
答案 1 :(得分:10)
pcollections怎么办?
您还可以查看Clojure的持久性集合实现(例如PersistentHashMap)。
答案 2 :(得分:5)
我一直在寻找一个苗条,Java"友好"持久集合框架并将此线程中提到的MoviePlayer和TotallyLazy用于testdrive,因为它们对我来说听起来最有希望。
两者都提供合理的简单接口来操作持久列表:
// TotallyLazy
PersistentList<String> original = PersistentList.constructors.empty(String.class);
PersistentList<String> modified = original.append("Mars").append("Raider").delete("Raider");
// PCollections
PVector<String> original = TreePVector.<String>empty();
PVector<String> modified = original.plus("Mars").plus("Raider").minus("Raider");
PersistentList
和PVector
都扩展java.util.List
,因此两个库都应该很好地集成到现有环境中。
我可以在PCollections上找到我的(简单)测试用例,如果有人想要更全面一点的话。
答案 3 :(得分:4)
https://github.com/andrewoma/dexx是Scala对Java的持久集合的一个端口。它包括:
答案 4 :(得分:3)
可能想查看clj-ds。我没有用它,但看起来很有希望。基于项目自述文件,它从Clojure 1.2.0中提取出数据结构。
答案 5 :(得分:3)
Functional Java实现持久List,惰性List,Set,Map和Tree。可能还有其他人,但我只是按照网站首页上的信息进行操作。
我也很想知道Java最好的持久数据结构库是什么。我的注意力集中在功能Java上,因为书中提到了Functional Programming for Java Developers。
答案 6 :(得分:3)
您可以使用pcollections
(持久收藏集)库:
答案 7 :(得分:3)
Paguro provides type-safe versions of the actual Clojure collections用于Java 8+。它包括:List(Vector),HashMap,TreeMap,HashSet和TreeSet。它们的行为与您在问题中指定的方式完全相同,并且painstakingly fit into the existing java.util
collections interfaces具有最大的类型安全Java兼容性。它们也是a little faster than PCollections。
在Paguro中编写您的示例看起来像这样:
// List with the elements (a,b,c)
ImList<T> list = vec(a,b,c);
// With a persistent list, when I call list.add(d),
// I get back a new list, holding (a,b,c,d)
ImList<T> newList = list.append(d);
list.size(); // still returns 3
newList.size(); // returns 4
你说,
实现尝试在列表之间共享元素 只要有可能,它的内存效率和速度都要高得多 只需返回原始列表的副本。它也有 不可变的优点(如果我持有对原始的引用 列表,然后它将始终返回原始的3个元素。)
是的,这正是它的表现。 Daniel Spiewak explains the speed and efficiency of these collections比我更好。
答案 8 :(得分:2)
与Cornelius Mund一样,Pure4J将Clojure集合移植到Java中并添加了泛型支持。
然而,Pure4J旨在通过编译时代码检查将纯编程语义引入JVM,因此它进一步向类引入不可变性约束,以便在集合存在时不能突变集合的元素。 / p>
这可能是你想要实现的,也可能不是你想要实现的:如果你刚刚在JVM上使用Clojure集合,我会采用Cornelius的方法,否则,如果你有兴趣在Java中寻求纯编程方法那么你可以尝试一下Pure4J。
披露:我是
的开发者答案 9 :(得分:1)
最高投票回答建议直接使用clojure集合,我认为这是一个非常好的主意。不幸的是,clojure是一种动态类型语言而Java不会使clojure库在Java中使用时非常不舒服。
由于这个以及缺乏用于clojure集合类型的轻量级,易于使用的包装器,我使用泛型为clojure集合类型编写了我自己的Java包装器库,重点是易用性和清晰度谈到接口。
https://github.com/cornim/ClojureCollections
也许这会对某人有用。
P.S。:目前只实施了PersistentVector,PersistentMap和PersistentList。
答案 10 :(得分:1)
totallylazy是一个非常好的FP库,具有以下实现:
PersistentList<T>
:具体实施是LinkedList<T>
和TreeList<T>
(用于随机访问)PersistentMap<K, V>
:具体实施是HashTreeMap<K, V>
和ListMap<K, V>
PersistentSortedMap<K, V>
PersistentSet<T>
:具体实施是TreeSet<T>
使用示例:
import static com.googlecode.totallylazy.collections.PersistentList.constructors.*;
import com.googlecode.totallylazy.collections.PersistentList;
import com.googlecode.totallylazy.numbers.Numbers;
...
PersistentList<Integer> list = list(1, 2, 3);
// Create a new list with 0 prepended
list = list.cons(0);
// Prints 0::1::2::3
System.out.println(list);
// Do some actions on this list (e.g. remove all even numbers)
list = list.filter(Numbers.odd);
// Prints 1::3
System.out.println(list);
完全保持不变。主要的缺点是完全没有Javadoc。
答案 11 :(得分:1)
我很惊讶没有人提到vavr。我已经使用了很长时间了。
他们网站上的描述
Vavr核心是Java的功能库。它有助于减少代码量并提高鲁棒性。进行函数式编程的第一步是开始思考不变的值。 Vavr提供不可变的集合以及必要的功能和控制结构,以对这些值进行操作。结果很漂亮,而且效果很好。
答案 12 :(得分:0)
https://github.com/arnohaase/a-foundation是Scala图书馆的另一个端口。
也可以从Maven Central获得:com.ajjpj.a-foundation:a-foundation