什么会更好?
假设我们的某个班级mainClass
有List<BigClass>
List<Foo>foos
....
Foo
本身有一个List<Boo>
如果目标是能够获得Boo
的所有元素的所有foos
。
如果用户要将新的List<Boo>
插入BigClass
,那么在Boo
中保留另一个Foo
并插入相应的foos
元素会更好吗?
或者每次用户要求此列表时,从“BigClass”中生成此总Boo
列表会更好吗?
这里的主要问题是,你必须在这里选择性能与内存吗?
PS。 抱歉广泛的标题,不太知道如何命名这个问题:/
答案 0 :(得分:2)
您可以将这两种行为都放在一个实现中。只需在mainClass中创建自己的List实现(可能是一个名为FooList的内部类,或者甚至是一个匿名的内部类)。使FooList的方法透明地将所有单个Foo列表作为单个列表呈现。例如,FooList.iterator()的实现将依次透明地在每个单独的Foo列表上实例化一个迭代器,这样它就会迭代通过一个大的列表。
答案 1 :(得分:1)
如果您需要获取所有Boo
并同时保持Boo
分组(即属于某些Boo
的{{1}}),那么我会最好的方法是返回Foo
中包含的所有Boo
的视图,无论它们属于哪个BigClass
。
要完成此操作,您可以使用Google Guava Iterables
或Java 8 Stream.flatMap()
,具体取决于您的Java版本。
使用Google Guava:
Foo
这种方法最好的是Guava返回的class BigClass {
List<Foo> foos = new LinkedList<Foo>();
public Iterable<Boo> allBoos() {
return Iterables.concat(this.foos);
}
}
class Boo {
final int a;
Boo(int a) {
this.a = a;
}
@Override
public String toString() {
return String.valueOf(this.a);
}
}
class Foo
implements Iterable<Boo> {
List<Boo> boos = new LinkedList<Boo>();
@Override
public Iterator<Boo> iterator() {
return this.boos.iterator();
}
}
public class Sample {
public static void main(String[] args) {
Boo b1 = new Boo(1);
Boo b3 = new Boo(3);
Boo b5 = new Boo(5);
Boo b2 = new Boo(2);
Boo b4 = new Boo(4);
Boo b6 = new Boo(6);
Foo odd = new Foo();
odd.boos.addAll(Arrays.asList(b1, b3, b5));
Foo even = new Foo();
even.boos.addAll(Arrays.asList(b2, b4, b6));
BigClass b = new BigClass();
b.foos.add(odd);
b.foos.add(even);
System.out.println(b.allBoos()); // [1, 3, 5, 2, 4, 6]
}
}
是 lazy ,这意味着没有创建新的集合或列表并填充任何元素。相反,返回的Iterable
是一个视图,其Iterable
消耗来自第一个Iterator
的元素,当用尽时,“跳转”到下一个Iterable
并消耗其元素, “跳转”到下一个,依此类推,直到消耗掉最后一个Iterable
的最后一个元素。
使用Java 8:
Iterable
laziness 的相同注意事项适用于此。