Java 如何返回常量集合

Java 如何返回常量集合,java,Java,在java中,有没有一种方法可以返回对类集合的引用,而我既不能更改它,也不能更改其元素的数据 因此,如果我有一个mapmap没有主体可以获取对设置值的引用并向其添加元素?您可以使用它来获取无法修改的映射视图 每种类型的集合都有不同的方法: unmodifiableCollection返回泛型集合的不可修改视图 unmodifiableSet返回集合的不可修改视图 unmodifiableList返回列表的不可修改视图 unmodifiableSortedSet返回SortedSet的不可修改视

在java中,有没有一种方法可以返回对类集合的引用,而我既不能更改它,也不能更改其元素的数据

因此,如果我有一个map
map
没有主体可以获取对设置值的引用并向其添加元素?

您可以使用它来获取无法修改的映射视图

每种类型的集合都有不同的方法:

  • unmodifiableCollection
    返回泛型集合的不可修改视图
  • unmodifiableSet
    返回集合的不可修改视图
  • unmodifiableList
    返回列表的不可修改视图
  • unmodifiableSortedSet
    返回SortedSet的不可修改视图
  • unmodifiableSortedMap
    返回SortedMap的不可修改视图
如果项本身是集合,则可以编写递归方法来构造一个新集合,该集合包含原始项的不可修改视图


一般来说,如果您存储在集合中的项目本身可以修改,那么除了制作防御性副本之外,没有任何东西可以阻止您这样做。

这是确保
映射
中的所有对象都不能修改的唯一方法,即使
映射本身是不可修改的,将使对象本身不可变

unmodifiableMap()
方法保证了
Map
不能被修改,但是它对它包含的对象没有任何保证。看一看,了解如何使对象不可变。有关具体示例,请参见
String
类的工作原理:不能修改字符串中的字符,所有可以更改字符串的方法(例如:
toUpperCase()
)都会返回新字符串。这就是您希望
贴图中对象的行为

假设问题中的映射包含
Set
作为其值,那么在将集合添加到映射之前对集合使用
Collections.unmodifiableSet()
,将使它们不可变,因为如上所述,
String
已经不可变。

Map<Integer, String> myMap =
            Collections.unmodifiableMap(new HashMap<Integer, String>() {
        {
            put(1, "value1");
            put(2, "value2");
            put(3, "value3");
        }
    });
Map myMap=
Collections.unmodifiableMap(新的HashMap(){
{
卖出(1,“价值1”);
卖出(2,“价值2”);
卖出(3,“价值3”);
}
});
名单:

List List=Collections.unmodifiableList(新的ArrayList(){
{
添加(“价值1”);
添加(“价值2”);
添加(“价值3”);
}
});
设置:

Set list=Collections.unmodifiableSet(新HashSet()){
{
添加(“价值1”);
添加(“价值2”);
添加(“价值3”);
}
});

通过您自己提供的方法,通过中介对外部集合(地图)的访问,可能最容易实现您的目标。然后,您可以在将相应的
Set
对象通过
Collections.unmodifiableSet()
后返回该对象

由于
String
是不可变的,因此在此之后调用方实际上没有什么可以更改的


除此之外,您必须构建一个新的
映射
,其中填充了所有通过
集合传递的集合。unmodifiableSet()
,然后通过
集合。unmodifiableMap()
传递该集合。但是,这可能是一个好主意,也可能不是一个好主意,这取决于你的收藏有多大。

你可以在交给某人之前克隆它,因此即使他更改了它,也不会影响你的程序,但如果它真的很大,这将太多了,我使用了它,而且它不起作用,我可以得到地图中某个值的引用并更改其数据。这是一个完全不同的问题!不可修改对象的集合与不可修改的集合完全不同。这个问题的答案是否定的。@Doggynub除了将
Map
装饰为不可修改之外,还应该将
Set
s元素装饰为不可修改。如果要对自己的类执行此操作,必须确保类也是不可变的。是的,我的对象是不可变的,但它们包含在集合中,那么递归函数如何?鉴于您只有一级嵌套集合(
Map
),您实际上不需要递归函数。只需构造一个新的映射并迭代现有映射的键和值,对每对映射执行
newMap.put(key,Collections.unmodifiableSet(value))
。有没有一种方法可以使该设置也不可变而不复制新内容?这只会使映射元素的副本不正确?该集合将从新映射中的不可变视图返回?正确,它是一个浅拷贝(这正是您希望它们不可变的原因)。我想既然
地图是复制的,以后就没有必要再修改它了。为了直接实现你的目标。。。我不知道有什么内在的方式。我认为您需要做一些事情,比如滚动您自己的不可修改映射实现,通过
unmodifiableSet()
传递返回值。
List<String> list = Collections.unmodifiableList(new ArrayList<String>() {
        {
            add("value1");
            add("value2");
            add("value3");
        }
    });
Set<String> list = Collections.unmodifiableSet(new HashSet<String>() {
        {
            add("value1");
            add("value2");
            add("value3");
        }
    });