如果需要都得到所有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