组合列表,然后从组件列表中删除

Combine lists, then remove from component list

List<Bean> one //blah;
List<Bean> two //blah;
List<Bean> three //blah;

List<Bean> myCombined = Lists.newArrayList();
myCombined.addAll(one);
myCombined.addAll(two);
myCombined.addAll(three);

那么如果我从基础列表中删除,它会从组合列表中删除吗?

one.remove(myBean)
one.contains(myBean); //false
myCombined.contains(myBean); //true or false ?

如果没有,最好的方法是什么?

myCombined.contains(myBean); 将 return 为真,因为列表是一个新对象并且不引用其他对象。

最好的方法是创建一个清除每个列表的方法

public void removeObject(Bean b)
{
    this.one.remove(myBean);
    this.myCombined.remove(myBean);
}

然后只需调用 removeObject(myBean)

查看 addAll 方法的示例(来自 ArrayList

public boolean addAll(Collection<? extends E> c) {
    Object[] a = c.toArray();
    int numNew = a.length;
    ensureCapacityInternal(size + numNew);  // Increments modCount
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
}

你可以清楚地看到它创建了一个副本。

实际上,两个列表都将引用同一个对象。因此从 one 改变将改变 myCombined.

one 中删除只会删除 one 中的引用,但 myCombined 会保留它自己的引用。

addAll 将元素从源列表复制到目标列表。

因此,从 one 中删除一个元素不会影响 myCombined

怎么办?

要查看列表,您可以使用 Guava Iterables.concat(...):

Iterable<Bean> combinedView = Iterables.concat(one, two, three);
Iterables.contains(combinedView, myBean);  // true
one.remove(myBean);
Iterables.contains(combinedView, myBean);  // false

你也可以使用Java流:

Stream<Bean> combined = Stream.of(one, two, three)
                              .reduce(Stream.empty(), Stream::concat)
                              .map(identity());

不,如果您从其中一个基础列表中删除一个元素,它不会从组合列表中 "disappear",因为组合列表是一个新列表,包含对元素的新引用。

要完成您想要的,您需要对基础列表进行 列表视图Google Guava library offers this by means of the Iterables.concat()方法:

Iterable<Bean> combined = Iterables.concat(one, two, three);

请注意,返回的 Iterable 不是 List,而只是 Iterable