不可变集合在修改时返回新视图

时间:2012-03-24 01:32:48

标签: java collections

首先,我不会问一个包装器的问题,它使得包装只读,例如Collections.unmodifableXXX。我的api会有一个不同的api,其中所有修饰符方法都会返回新的集合。

像简单列表之类的东西将不再具有void set方法,但会返回一个新的List。

理想情况下,包将包含List,Set,Map甚至无聊Stack的相同不可变变量。

更新

// i am omitting generics etc to keep things simple.
XList list = List.fromArray( 1, 2, 3 );
XList list2 = list.add( 4 );

System.out.println( list ); // 1, 2, 3 
System.out.println( list2 ); // 1, 2, 3, 4

删除,设置等都会在更新元素等后返回不同的列表。

5 个答案:

答案 0 :(得分:2)

实际上,我认为OP正在描述功能集合API。这可以使用copy-on-write实现,但关键区别在于API设计本身。

我找不到像这样工作的替代Java集合框架。这并不是说你不能写一个......

(标准的Java copy-on-write集合是可变的,在大多数方面表现得像“普通”集合。在这些类中使用写时复制机制的目的是允许并发迭代和修改,以及减少了大量线程争用的共享集合上的同步开销。)

答案 1 :(得分:1)

您所描述的内容称为" copy-on-write",Java有两种此类集合的实现:CopyOnWriteArrayListCopyOnWriteArraySet

答案 2 :(得分:0)

答案 3 :(得分:0)

Clojure programming language(编译为Java字节代码,在JVM上运行,并且与Java完全可互操作)具有与您正在寻找的语义完全相同的集合。

这是一个概述页面,描述了Clojure数据结构背后的一般原理:http://clojure.org/data_structures

虽然Clojure有自己的类似Lisp的语法,但它的大多数库函数都是用Java实现的。例如,Clojure列表由PersistentList.java定义。您可以在任何Java程序中导入和使用此类。 Clojure有类似的集合,地图等类......

答案 4 :(得分:0)

您无法在vanilla Collections框架内执行此操作,例如Collection.add(Object)被指定为返回boolean,您无法覆盖它以返回新的Collection

您可以尝试使用Functional Java中的数据结构。