Cách chung nhất để giải quyết các tác vụ như vậy là kết hợp kết quả của nhiều người sưu tập thành một bộ duy nhất.
Sử dụng thư viện jOOL, bạn có thể có những điều sau đây:
Content content =
Seq.seq(contentList)
.collect(
Collectors.mapping(Content::getA, Collectors.joining(", ")),
Collectors.mapping(Content::getB, Collectors.joining(", ")),
Collectors.mapping(Content::getC, Collectors.joining(", "))
).map(Content::new);
này tạo ra một Seq
từ danh sách đầu vào và kết hợp 3 nhà sưu tập được để tạo ra một Tuple3
, mà chỉ đơn giản là một người giữ cho 3 giá trị. Sau đó, 3 giá trị đó được ánh xạ thành một Content
bằng cách sử dụng hàm tạo new Content(a, b, c)
. Bản thân người sưu tập chỉ đơn giản là ánh xạ mỗi Content
vào giá trị a
, b
hoặc c
và tham gia các kết quả cùng nhau được tách riêng với ", "
.
Nếu không có bên thứ ba giúp đỡ, chúng ta có thể tạo ra thu kết hợp của chúng ta như thế này (điều này được dựa trên StreamExpairing
nhà sưu tập, mà làm điều tương tự cho 2 nhà sưu tập). Phải mất 3 nhà sưu tập làm đối số và thực hiện một hoạt động kết thúc trên kết quả của 3 giá trị được thu thập.
public interface TriFunction<T, U, V, R> {
R apply(T t, U u, V v);
}
public static <T, A1, A2, A3, R1, R2, R3, R> Collector<T, ?, R> combining(Collector<? super T, A1, R1> c1, Collector<? super T, A2, R2> c2, Collector<? super T, A3, R3> c3, TriFunction<? super R1, ? super R2, ? super R3, ? extends R> finisher) {
final class Box<A, B, C> {
A a; B b; C c;
Box(A a, B b, C c) {
this.a = a;
this.b = b;
this.c = c;
}
}
EnumSet<Characteristics> c = EnumSet.noneOf(Characteristics.class);
c.addAll(c1.characteristics());
c.retainAll(c2.characteristics());
c.retainAll(c3.characteristics());
c.remove(Characteristics.IDENTITY_FINISH);
return Collector.of(
() -> new Box<>(c1.supplier().get(), c2.supplier().get(), c3.supplier().get()),
(acc, v) -> {
c1.accumulator().accept(acc.a, v);
c2.accumulator().accept(acc.b, v);
c3.accumulator().accept(acc.c, v);
},
(acc1, acc2) -> {
acc1.a = c1.combiner().apply(acc1.a, acc2.a);
acc1.b = c2.combiner().apply(acc1.b, acc2.b);
acc1.c = c3.combiner().apply(acc1.c, acc2.c);
return acc1;
},
acc -> finisher.apply(c1.finisher().apply(acc.a), c2.finisher().apply(acc.b), c3.finisher().apply(acc.c)),
c.toArray(new Characteristics[c.size()])
);
}
và cuối cùng là sử dụng nó với
Content content = contentList.stream().collect(combining(
Collectors.mapping(Content::getA, Collectors.joining(", ")),
Collectors.mapping(Content::getB, Collectors.joining(", ")),
Collectors.mapping(Content::getC, Collectors.joining(", ")),
Content::new
));
mô tả vấn đề tốt. Nhưng bây giờ, bạn đã thử cái gì? StackOverflow không phải là một cộng đồng để người khác viết mã cho bạn. Thay vào đó, bạn cần đăng một [mcve] hiển thị những gì bạn đã thử, những gì bạn có và những gì bạn mong đợi và cộng đồng StackOverflow có thể cố gắng giúp xác định nơi bạn đã đi sai và chỉ ra các giải pháp. – AJNeufeld
@AJNeufeld cảm ơn đề xuất. Đây cũng là lần đầu tiên tôi cố gắng đăng câu hỏi trên SO mặc dù sử dụng nó mỗi ngày. Tôi có nó làm việc với một vòng lặp cơ bản với một biến để nối thêm nội dung. Và tôi đã thử sử dụng forEach trên luồng rồi nhận ra rằng các hàm ẩn danh Java không cho phép sửa đổi biến bên trong khối foreach. Ngoài ra tôi đã suy ngẫm về việc viết một thu thập để đạt được một nhưng nhận ra nó sẽ không hiệu quả hoặc. – Vedanth