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

时间:2015-03-27 17:33:18

标签: java collections

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 ?

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

4 个答案:

答案 0 :(得分:3)

myCombined.contains(myBean);将返回true,因为List是一个新对象,而不是引用另一个。

执行此操作的最佳方法是创建一个清除每个列表的方法

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;
}

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

答案 1 :(得分:2)

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

one中删除只会删除one中的引用,但myCombined会跟踪自己的引用。

答案 2 :(得分:2)

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:

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

答案 3 :(得分:2)

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

要完成您想要的任务,您需要在基础列表上使用列表视图Google Guava library通过Iterables.concat()方法提供此功能:

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

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