- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有以下 Set
Set<String> fruits = new HashSet<String>();
fruits.add("Apple")
fruits.add("Grapes")
fruits.add("Orange")
如果我想创建一个防御性副本,以便如果原始列表被修改,副本不会反射(reflect)它,我可以这样做:
Set<String> unmodifiableFruits = Collections.unmodifiableSet(new HashSet(fruits))
所以如果我这样做:
fruits.add("Pineapple")
println(unmodifiableFruits)
unmodifiableFruits
不会有菠萝。
或者我可以这样:
Set<String> unmodifiableFruits = Collections.unmodifiableCollection(fruits)
结果是一样的,unmodifiableFruits
不会有菠萝。
问题:
fruits
作为类的参数,首选方法是 Collections.unmodifiableCollection()
? 原因是,我已经 read声明new
如果我要使用 Collections.unmodifiableSet()
在构造函数中是一个不好的做法,我需要声明 new HashSet<String>(fruits)
.
为什么我不能这样做?
Collections.unmodifiableSet(fruits)
并让它返回一个不可修改的集合。
相反,我必须这样做:
Collections.unmodifiableSet(new HashSet<String>(fruits))
是不是因为Set是一个接口(interface),它不知道返回哪个实现?
最佳答案
Groovy 增强了集合方法,这意味着它向标准集合类添加了方法。
其中一个方法是 toSet()
:
Convert a Collection to a Set. Always returns a new Set even if the Collection is already a Set.
Example usage:
def result = [1, 2, 2, 2, 3].toSet()
assert result instanceof Set
assert result == [1, 2, 3] as Set
当你写下这个:
Set<String> unmodifiableFruits = Collections.unmodifiableCollection(fruits)
它意味着调用 .toSet()
来将 unmodifyingCollection
返回的 Collection
强制转换为 Set
, 隐式复制数据。
当你写下这个:
Set<String> unmodifiableFruits = Collections.unmodifiableSet(fruits)
返回的值已经是一个Set
,因此不会调用toSet()
,这意味着unmodifyingFruits
和fruits
共享数据。
这就是为什么在使用 unmodifyingSet
时必须通过添加 new HashSet(...)
来显式复制数据。
Is using
Collections.unmodifiableCollection()
the proper way when passing a set into the constructor?
绝对不是。使用 unmodifyingCollection()
并分配给 Set
,隐式调用 toSet
复制数据,隐藏了执行复制的事实。
为了确保代码的可读性,即任何阅读代码的人(包括 3 年后的你自己)都会理解它的作用,请使用复制构造函数编写代码来显式复制数据。
嗯,当然,除非这是代码混淆的练习,在这种情况下,这是一个很好的误导性技巧。
关于java - Collections.unmodifyingCollection 和 Collections.unmodifyingSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52068311/
假设我有以下 Set Set fruits = new HashSet(); fruits.add("Apple") fruits.add("Grapes") fruits.add("Orange")
我是一名优秀的程序员,十分优秀!