我想创建一个列表视图,其中包含许多其他列表的串联。
示例:
List<Integer> l1 = Lists.newArrayList(1);
List<Integer> l2 = Lists.newArrayList(2);
List<Integer> l3 = Lists.newArrayList(3);
// This call should not copy any of the argument lists content
List<Integer> concatenation = new ConcatenationListView(l1, l2, l3);
System.out.println(concatenation); // Prints [1, 2, 3]
l3.add(4);
System.out.println(concatenation); // Prints [1, 2, 3, 4]
我可以在Java中使用哪种技术和/或模式来满足这些要求?
List.subList
方法相反。Iterables.concat
方法所做的,但我需要一个列表作为结果,而不是可迭代的。List
作为结果连接,其他问题的海报内容为Iterable
。答案 0 :(得分:1)
Java类库没有这样的组合类,因此您需要自己编写代码。
由于您希望类允许修改基础列表,因此效率不会高于O(L),其中L
是视图管理的列表数,因为索引转换需要您每次需要读取或插入特定索引时,都要遍历列表列表。
另一方面,这使得实现变得非常简单 - 翻译索引的代码如下所示:
class ListView : List<T> {
private List<List<T>> lists = ...
public T get(int index) {
int i = 0;
while (i != lists.size() && index > lists.get(i).size()) {
index -= lists.get(i++).size();
}
if (i == lists.size()) {
throw new IndexOutOfBoundsException();
}
return lists.get(i).get(index);
}
...
}
答案 1 :(得分:0)
以下是一个类的实现,它充当多个列表串联的视图。
它没有采取多行措施:
/**
* A list which acts as view of the concatenation of a number of lists.
*/
public class ListConcatenationView<E> extends AbstractList<E> {
private final List<E>[] lists;
@SafeVarargs
public ListConcatenationView(List<E>... lists) {
this.lists = lists;
}
@Override
public E get(int ix) {
int localIx = ix;
for (List<E> l : lists) {
if (localIx < 0) throw new IndexOutOfBoundsException(ix);
if (localIx < l.size()) return l.get(localIx);
localIx -= l.size();
}
return null;
}
@Override
public int size() {
int size = 0;
for (List<E> l : lists) {
size += l.size();
}
return size;
}
}
答案 2 :(得分:-1)
你可以使用Java8 Stream-API作为这个。
Stream.of(l1, l2, l3)
.flatMap(List::stream)
.forEach(System.out::println);
这将创建三个列表的Stream,然后通过将每个列表转换为流本身(List::stream
)并将它们平面映射在一起来将每个列表中的所有项连接在一起。毕竟它输出控制台上的每一个元素。
Plus:默认情况下Streams是懒惰的,这意味着
源数据的计算仅在启动终端操作时执行,源元素仅在需要时使用。