如何在java中创建不可变列表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30348292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create Immutable List in java?
提问by
I need to convert mutable list object to immutable list. What is the possible way in java?
我需要将可变列表对象转换为不可变列表。java中可能的方法是什么?
public void action() {
List<MutableClass> mutableList = Arrays.asList(new MutableClass("san", "UK", 21), new MutableClass("peter", "US", 34));
List<MutableClass> immutableList = immutateList(mutableList);
}
public List<MutableClass> immutateList(List<MutableClass> mutableList){
//some code here to make this beanList immutable
//ie. objects and size of beanList should not be change.
//ie. we cant add new object here.
//ie. we cant remove or change existing one.
}
MutableClass
MutableClass
final class MutableClass {
final String name;
final String address;
final int age;
MutableClass(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
}
采纳答案by aioobe
Once your beanList
has been initialized, you can do
一旦你beanList
被初始化,你可以做
beanList = Collections.unmodifiableList(beanList);
to make it unmodifiable. (See Immutable vs Unmodifiable collection)
使其不可修改。(请参阅不可变与不可修改集合)
If you have both internal methods that should be able to modify the list, and public methods that should not allow modification, I'd suggest you do
如果您同时拥有应该能够修改列表的内部方法和不允许修改的公共方法,我建议您这样做
// public facing method where clients should not be able to modify list
public List<Bean> getImmutableList(int size) {
return Collections.unmodifiableList(getMutableList(size));
}
// private internal method (to be used from main in your case)
private List<Bean> getMutableList(int size) {
List<Bean> beanList = new ArrayList<Bean>();
int i = 0;
while(i < size) {
Bean bean = new Bean("name" + i, "address" + i, i + 18);
beanList.add(bean);
i++;
}
return beanList;
}
(Your Bean
objects already seem immutable.)
(您的Bean
对象似乎已经是不可变的。)
As a side-note: If you happen to be using Java 8+, your getMutableList
can be expressed as follows:
附带说明:如果您碰巧使用的是 Java 8+,getMutableList
则可以表示如下:
return IntStream.range(0, size)
.mapToObj(i -> new Bean("name" + i, "address" + i, i + 18))
.collect(Collectors.toCollection(ArrayList::new));
回答by Mad Physicist
Use Collections.unmodifiableList()
. You pass in your original ArrayList
and it returns a list that throws an exception if you try to add, remove or shift elements. For example, use return Collections.unmodifiableList(beanList);
instead of return beanList;
at the end of getImmutableList()
. main()
will throw an exception. The Collections
class has methods for all of the other common collection types besides list as well.
使用Collections.unmodifiableList()
. 您传入原始文件ArrayList
,如果您尝试添加、删除或移动元素,它会返回一个抛出异常的列表。例如,使用return Collections.unmodifiableList(beanList);
代替return beanList;
在的端部getImmutableList()
。main()
会抛出异常。Collections
除了列表之外,该类还具有用于所有其他常见集合类型的方法。
回答by Ashish Agrawal Yodlee
Below solution is for making list as Immutable without using any API.
下面的解决方案是在不使用任何 API 的情况下将列表设为不可变。
Immutable Object with ArrayList member variable
具有 ArrayList 成员变量的不可变对象
public final class Demo {
private final List<String> list = new ArrayList<String>();
public Demo() {
list.add("A");
list.add("B");
}
public List<String> getImmutableList() {
List<String> finalList = new ArrayList<String>();
list.forEach(s -> finalList.add(s));
return finalList;
}
public static void main(String[] args) {
Demo obj = new Demo();
System.out.println(obj.getImmutableList());
obj.getImmutableList().add("C");
System.out.println(obj.getImmutableList());
}
}
So the actual list will not change, always output will be [A,B]
所以实际列表不会改变,总是输出 [A,B]
回答by tonyhoan
From Java 10 on, List.copyOf(Collection)
can be used to return an unmodifiable list from the given collection. From source code of List.copyOf
method:
从 Java 10 开始,List.copyOf(Collection)
可用于从给定集合返回不可修改的列表。从List.copyOf
方法的源代码:
if the given collection is an unmodifiable List,
List.copyOf()
will not create a copy.if the given collection is mutable and modified, the returned list will not reflect such modifications. Meaning they are dependent.
如果给定的集合是不可修改的列表,
List.copyOf()
则不会创建副本。如果给定的集合是可变的并被修改,则返回的列表将不会反映此类修改。意味着他们是依赖的。
回答by Roushan
回答by Donald Raab
If are open to using a third party library, Eclipse Collections lets you convert from MutableList
to ImmutableList
and back again.
如果是开放的使用第三方库,Eclipse的收藏小号让您从转换MutableList
到ImmutableList
,然后再返回。
MutableList<String> mutable = Lists.mutable.with("a", "b", "c");
ImmutableList<String> immutable = mutable.toImmutable();
MutableList<String> mutableAgain = immutable.toList();
This also works with primitive collections.
这也适用于原始集合。
MutableCharList mutable = CharLists.mutable.with('a', 'b', 'c');
ImmutableCharList immutable = mutable.toImmutable();
MutableCharList mutableAgain = immutable.toList();
If you have an ArrayList
as the mutable List
, the following will work.
如果您有一个ArrayList
作为 mutable List
,以下将起作用。
List<String> mutable = new ArrayList<>(Arrays.asList("a", "b", "c"));
ImmutableList<String> immutable = Lists.immutable.withAll(mutable);
List<String> mutableAgain = immutable.toList();
Note: I am a committer for Eclipse Collections.
注意:我是 Eclipse Collections 的提交者。
回答by Saurabh
Make it immutable instead of using directly unmodifiableList on list as otherwise still original list can be changed.
使其不可变,而不是直接在列表上使用 unmodifiableList,否则原始列表仍然可以更改。
Basically unModifiable Collection is a view, So indirectly it could still be 'modified' from some other reference that is modifiable. Also as its just a readonly view of annother collection , When the source collection changes unModifiable Collection will always present with latest values.
基本上 unModifiable Collection 是一个视图,所以间接地它仍然可以从其他一些可修改的引用中“修改”。也因为它只是另一个集合的只读视图,当源集合更改时, unModifiable 集合将始终显示最新值。
However immutable Collection can be treated as a readonly copy of another collection and can not be modified. In this case when the source collection changes , immutable Collection do not reflect the changes
然而,不可变集合可以被视为另一个集合的只读副本并且不能被修改。在这种情况下,当源集合更改时,不可变集合不会反映更改
List<String> immutableList=Collections.unmodifiableList(
new ArrayList<String>(modifiableList));
Using guava:
使用番石榴:
import java.util.*;
import com.google.common.collect.ImmutableList;
ImmutableList<String> iList = ImmutableList.copyOf(list);