ses*_*ses 6 java collections guava
我想感受copyOf()番石榴方法的"神奇力量" guava-libraries.
有一个小应用程序,我用来检查它.
这是文档:
JDK提供了
Collections.unmodifiableXXX方法,但在我们看来,这些方法可以
- 笨拙而冗长; 在你想要制作防御性副本的任何地方使用都是不愉快的
- unsafe:如果没有人拥有对原始集合的引用,则返回的集合只是真正不可变的
所以,我尝试在哪里建立一个模型"someone holds a reference to the original collection".因此,使用集合的副本我不应该担心改变副本的价值.但魔法到目前为止还不起作用(有两次尝试:1.copyOf(collection),2.copyOf(iterator)):
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import java.util.List;
class MyObject {
String name;
public MyObject(String name) {this.name = name;}
@Override
public String toString() {
return name;
}
}
public class ListUnsafe {
List<MyObject> list = new LinkedList<MyObject>();
{
list.add(new MyObject("a"));
list.add(new MyObject("b"));
list.add(new MyObject("c"));
}
public List<MyObject> getList() {
return ImmutableList.copyOf(list);
}
public List<MyObject> getCopyIterator() {
return ImmutableList.copyOf(list.iterator());
}
public static void main(String[] args) {
ListUnsafe obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getList();
MyObject copyObj = myList.get(0);
copyObj.name = "new";
System.out.println("ref: " + ref);
}
obj = new ListUnsafe();
{
MyObject ref = obj.list.get(0);
List<MyObject> myList = obj.getCopyIterator();
MyObject copyObj = myList.iterator().next();
copyObj.name = "new";
System.out.println("ref: " + ref);
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
ref: new
ref: new
Run Code Online (Sandbox Code Playgroud)
这意味着我们改变了原始数据.我们不想要的.
为什么不复制?
它有何不同unmodifiableXXX?
有类似问题的链接:
答案说copyOf:
copyOf(Collection)实例不会创建临时ArrayList(copyOf(Iterable)并copyOf(Iterator)执行此操作).Lou*_*man 17
ImmutableList不会神奇地使元素不可变; 它是无法修改的列表,而不是它包含的元素.ImmutableList.copyOf进行复印,除非它被复制列表是已经的ImmutableList.如果您ImmutableList.copyOf(list)为同一个不可变列表调用两次,您将获得两个不同的副本.首先感谢大家的回答。我想出了一个让我满意的例子。这显示了ImmutableSet.copyOf(..)和 JDK之间的区别Collections.unmodifiableSet(..);
是的:它does shallow copy(否则它很奇怪,因为它很神奇)。
class Person {
public Person(String name) {this.name = name;}
public Person(String name, Person relation) {this(name);this.relation = relation;}
String name;
Person relation;
}
public class ImmutableExample {
public static void main(String[] args) {
Person bob = new Person("bob");
Person chris = new Person("chris", bob);
Person nullPerson = null; // NULL!
final Set<Person> originalSet = new LinkedHashSet<Person>(Arrays.asList(
bob,
chris
// nullPerson // NULL ! <- if we use null then we can not convert it to ImmutableSet
));
Set<Person> googleSet = ImmutableSet.copyOf(originalSet);
Set<Person> javaSet = Collections.unmodifiableSet(originalSet);
// is it SAFE to delete someone from original collection?
originalSet.remove(chris);
// google
for (Person person : googleSet) System.out.println(person.name); // Chris is still here! And this is good! Stay with us, Chris!
// java standard
for (Person person : javaSet) System.out.println(person.name); // Where is Chris ??
//newSet.add(new Person("newGuy")); // UnsupportedOperationException
}
}
Run Code Online (Sandbox Code Playgroud)
(原始问题的目的是为客户提供绝对安全的阅读列表。但这只能通过手动克隆列表中的所有对象来实现[如果它们不是不可变的]。提供更好的东西(就不变性和并发安全性)比CopyOnWriteArrayList。我的意思是:它提供安全
iterator,但不提供数据本身,如果它们在返回列表中是可变的 - 客户端仍然可以使用对返回(通过 getter)数据项的引用来更改数据)
| 归档时间: |
|
| 查看次数: |
17470 次 |
| 最近记录: |