次のようなオブジェクトがあります。
class House {
String name;
List<Door> doors;
}
私がやりたいことは、List<House>
aList<Door>
を all doors
of allを含む に変換することhouses
です。
グアバでこれを行う機会はありますか?
Lists.transform 関数を使用してグアバを試しましたがList<List<Door>>
、結果としてのみ取得しました。
本当に関数型アプローチを使用する必要がある場合は、FluentIterable#transformAndConcatを使用してこれを行うことができます。
public static ImmutableList<Door> foo(List<House> houses) {
return FluentIterable
.from(houses)
.transformAndConcat(GetDoorsFunction.INSTANCE)
.toImmutableList();
}
private enum GetDoorsFunction implements Function<House, List<Door>> {
INSTANCE;
@Override
public List<Door> apply(House input) {
return input.getDoors();
}
}
FluentIterable.from(listOfHouses).transformAndConcat(doorFunction)
うまく仕事をするでしょう。
Guava は必要ありません (私があなたを正しく理解していると仮定して):
final List<Door> doorsFromAllHouses = Lists.newArrayList();
for (final House house : houses) {
doorsFromAllHouses.addAll(house.doors);
}
// and doorsFromAllHouses is full of all kinds of doors from various houses
Lists.transform
入力list of houses
と変換関数に使用すると、get all doors from a house
正しい出力が得られましlist of *each house's doors*
た(正確には ですList<List<Door>>
)。
より一般的には、Guava では実装されていない変換の代わりにreduce
/ fold
functionが必要です(この問題を参照)。これは主に、Java の冗長な構文と for-each ループの存在が十分に優れているためです。Java 8 で削減できます (または、最近の他の主流言語でこれを行うことができます...)。疑似 Java8 コード:
List<Door> doors = reduce(
houses, // collection to reduce from
new ArrayList<Door>(), // initial accumulator value
house, acc -> acc.addAll(house.doors)); // reducing function