what's a good persistent collections framework for use in java?

前端 未结 13 1416
-上瘾入骨i
-上瘾入骨i 2020-12-01 06:39

By persistent collections I mean collections like those in clojure.

For example, I have a list with the elements (a,b,c). With a normal list, if I add d, my original

相关标签:
13条回答
  • 2020-12-01 07:00

    In the same vein as Cornelius Mund, Pure4J ports the Clojure collections into Java and adds Generics support.

    However, Pure4J is aimed at introducing pure programming semantics to the JVM through compile time code checking, so it goes further to introduce immutability constraints to your classes, so that the elements of the collection cannot be mutated while the collection exists.

    This may or may not be what you want to achieve: if you are just after using the Clojure collections on the JVM I would go with Cornelius' approach, otherwise, if you are interested in pursuing a pure programming approach within Java then you could give Pure4J a try.

    Disclosure: I am the developer of this

    0 讨论(0)
  • 2020-12-01 07:01

    Paguro provides type-safe versions of the actual Clojure collections for use in Java 8+. It includes: List (Vector), HashMap, TreeMap, HashSet, and TreeSet. They behave exactly the way you specify in your question and have been painstakingly fit into the existing java.util collections interfaces for maximum type-safe Java compatibility. They are also a little faster than PCollections.

    Coding your example in Paguro looks like this:

    // 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
    

    You said,

    The implementation attempts to share elements between the list wherever possible, so it's much more memory efficient and fast than simply returning a copy of the original list. It also has the advantage of being immutable (if I hold a reference to the original list, then it will always return the original 3 elements).

    Yes, that's exactly how it behaves. Daniel Spiewak explains the speed and efficiency of these collections much better than I could.

    0 讨论(0)
  • 2020-12-01 07:05

    https://github.com/arnohaase/a-foundation is another port of Scala's libraries.

    It is also available from Maven Central: com.ajjpj.a-foundation:a-foundation

    0 讨论(0)
  • 2020-12-01 07:06

    The top voted answer suggest to directly use the clojure collections which I think is a very good idea. Unfortunately the fact that clojure is a dynamically typed language and Java is not makes the clojure libraries very uncomfortable to use in Java.

    Because of this and the lack of light-weight, easy-to-use wrappers for the clojure collections types I have written my own library of Java wrappers using generics for the clojure collection types with a focus on ease of use and clarity when it comes to interfaces.

    https://github.com/cornim/ClojureCollections

    Maybe this will be of use to somebody.

    P.S.: At the moment only PersistentVector, PersistentMap and PersistentList have been implemented.

    0 讨论(0)
  • 2020-12-01 07:08

    I was looking for a slim, Java "friendly" persistent collection framework and took TotallyLazy and PCollections mentioned in this thread for a testdrive, because they sounded most promising to me.

    Both provide reasonable simple interfaces to manipulate persistent lists:

    // 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");
    

    Both PersistentList and PVector extend java.util.List, so both libraries should integrate well into an existing environment.

    It turns out, however, that TotallyLazy runs into performance problems when dealing with larger lists (as already mentioned in a comment above by @levantpied). On my MacBook Pro (Late 2013) inserting 100.000 elements and returning the immutable list took TotallyLazy ~2000ms, whereas PCollections finished within ~120ms.

    My (simple) test cases are available on Bitbucket, if someone wants to take a more thorough look.

    [UPDATE]: I recently had a look at Cyclops X, which is a high performing and more complete lib targeted for functional programming. Cyclops also contains a module for persistent collections.

    0 讨论(0)
  • 2020-12-01 07:09

    What about pcollections?

    You can also check out Clojure's implementation of persistent collections (PersistentHashMap, for instance).

    0 讨论(0)
提交回复
热议问题