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

Java 修改时返回新视图的不可变集合,java,collections,Java,Collections,首先,我不是在问一个包装器的问题,这个包装器使包装后的文件成为只读的,比如Collections.unmodifalexxx。我的api将有一个不同的api,其中所有修饰符方法都将返回新集合 类似于简单列表的东西将不再具有void set方法,而是返回一个新列表 理想情况下,该包将包含相同的不变的列表、集合、映射甚至堆栈变体 更新 // i am omitting generics etc to keep things simple. XList list = List.fromArray( 1

首先,我不是在问一个包装器的问题,这个包装器使包装后的文件成为只读的,比如Collections.unmodifalexxx。我的api将有一个不同的api,其中所有修饰符方法都将返回新集合

类似于简单列表的东西将不再具有void set方法,而是返回一个新列表

理想情况下,该包将包含相同的不变的列表、集合、映射甚至堆栈变体

更新

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

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

使用java 5中的“写时拷贝”集合如何


您所描述的被称为“写时复制”,Java有两种此类集合的实现:实际上,我认为OP描述的是函数集合API。这可以使用写时复制实现,但关键区别在于API设计本身

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

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

(它编译成Java字节码,在JVM上运行,并且与Java完全互操作)具有与您所寻找的语义完全相同的集合

下面是一个概述页面,介绍Clojure数据结构背后的一般原则:


尽管Clojure有自己的类似Lisp的语法,但它的大多数库函数都是用Java实现的。例如,Clojure列表由定义。您可以在任何Java程序中导入并使用此类。Clojure有类似的集合、映射等类。

您不能在vanilla Collections框架中实现,因为n、 add(Object)被指定为返回一个
布尔值
,您不能替代它来返回一个新的
集合


您可能会尝试中的数据结构。

您考虑过使用吗?但不确定在Java中效果如何……您所描述的是“写时复制”.@jimGarrison我要求实例保持不变,你实际上描述了COW在后台数组内部的工作方式。@jordao由于缺少闭包,在Java中使用scala类不太合适。@mP:那么看看……COWAL和COWAS不会返回带有更改的新实例。这使得用于保存前后版本。我知道JVM上的其他语言也有类似的集合,但我希望留在java领域。
Functional java
据我所知不是另一种语言,它只是一个java库。目前这几乎是一个合适的答案。