如果需要都得到所有Boo
S和也保持Boo
与分组(即Boo
s表示属于某个Foo
),那么我会说,最好将返回的视图所有Boo
包含在BigClass
中,不管它们属于哪个Foo
。
要完成此操作,您可以使用Google Guava Iterables
或Java 8 Stream.flatMap()
,具体取决于您的Java版本。
与谷歌番石榴:
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]
}
}
最好的这种做法的是,该番石榴返回Iterable
是懒,这意味着没有新的集合或列表中创建并填充任何元素。相反,返回的Iterable
是一个视图,其消耗第一个Iterable
中的元素,并在用尽时“跳转”到下一个Iterable
并消耗其元素,并跳转到下一个元素,依此类推,直到最后一个元素最后的Iterable
被消耗。
与Java 8:
class BigClass {
List<Foo> foos = new LinkedList<Foo>();
public Iterable<Boo> allBoos() {
Stream<Boo> s = this.foos.stream().flatMap(
f -> f.getBoos().stream());
return s::iterator;
}
}
class Boo {
final int a;
Boo(int a) {
this.a = a;
}
@Override
public String toString() {
return String.valueOf(this.a);
}
}
class Foo {
List<Boo> boos = new LinkedList<Boo>();
public List<Boo> getBoos() {
return this.boos;
}
}
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);
List<Boo> list = new ArrayList<>();
b.allBoos().forEach(boo -> list.add(boo));
System.out.println(list); // [1, 3, 5, 2, 4, 6]
}
}
关于懒惰同样的考虑也适用于此。
使用最容易理解的方法。这是主要关心的问题。性能或内存不要担心,直到它是一个问题,因为它可能不会。 – 2015-03-13 17:36:28
*你会不得不在这里选择性能vs内存*:是的,很明显。您还必须考虑正确性,可维护性,健壮性和可读性。第二种解决方案比第一种解决方案简单得多。 – 2015-03-13 17:37:32
@JBNizet,是的,但如果做得对。第一个选项会是首选吗? – 2015-03-13 17:44:17