次のJava6およびJava8コードがあります。
List<ObjectType1> lst1 = // a list of ObjectType1 objects
List<ObjectType2> lst2 = // a list of ObjectType1 objects, same size of lst1
List<ObjectType3> lst3 = new ArrayLis<ObjectType3>(lst1.size());
for(int i=0; i < lst1.size(); i++){
lst3.add(new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal()));
}
Java8でLambdaを使用して以前のものをより簡潔に処理する方法はありますか?
ストリームは指定された反復可能/コレクションに関連付けられているため、2つのコレクションを並行して「反復」することはできません。
回避策の1つは、インデックスのストリームを作成することですが、それでは必ずしもforループで改善されるとは限りません。ストリームバージョンは次のようになります。
List<ObjectType3> lst3 = IntStream.range(0, lst1.size())
.mapToObj(i -> new ObjectType3(lst1.get(i).getAVal(), lst2.get(i).getAnotherVal()))
.collect(toList());
次のように、2つのコレクションを新しいコレクションに変換するメソッドを作成できます。
_public <T, U, R> Collection<R> singleCollectionOf(final Collection<T> collectionA, final Collection<U> collectionB, final Supplier<Collection<R>> supplier, final BiFunction<T, U, R> mapper) {
if (Objects.requireNonNull(collectionA).size() != Objects.requireNonNull(collectionB).size()) {
throw new IllegalArgumentException();
}
Objects.requireNonNull(supplier);
Objects.requireNonNull(mapper);
Iterator<T> iteratorA = collectionA.iterator();
Iterator<U> iteratorB = collectionB.iterator();
Collection<R> returnCollection = supplier.get();
while (iteratorA.hasNext() && iteratorB.hasNext()) {
returnCollection.add(mapper.apply(iteratorA.next(), iteratorB.next()));
}
return returnCollection;
}
_
ここで重要なのは、取得したiteratorA.next()
とiteratorB.next()
を新しいオブジェクトにマップすることです。
次のように呼び出されます。
_List<Integer> list1 = IntStream.range(0, 10).boxed().collect(Collectors.toList());
List<Integer> list2 = IntStream.range(0, 10).map(n -> n * n + 1).boxed().collect(Collectors.toList());
singleCollectionOf(list1, list2, ArrayList::new, Pair::new).stream().forEach(System.out::println);
_
あなたの例では:
_List<ObjectType3> lst3 = singleCollectionOf(lst1, lst2, ArrayList::new, ObjectType3::new);
_
たとえば、_Pair::new
_はlamdda _(t, u) -> new Pair(t, u)
_の省略形です。
あるストリームを別のストリームに更新する方法を見つけていませんが、マップを使用して同様の偉業を達成しました。 :)
Map<Integer, String> result = new HashMap<>();
for(int index = 100; index > 0; index--){
result.put(index, String.valueOf(index));
}
result.keySet().stream()
.filter(key -> key%3 == 0)
.sorted()
.forEach(key -> result.put(key, "Fizz"));
result.keySet().stream()
.filter(key -> key%5 == 0)
.sorted()
.forEach(key -> result.put(key, "Buzz"));
result.keySet().stream()
.filter(key -> key%3 == 0 && key%5 == 0)
.sorted()
.forEach(key -> result.put(key, "FizzBuzz"));
result.keySet().stream().forEach(key -> System.out.println(result.get(key)));