내가있는 경우 Java 8의 기능을 사용하여 동일한 반복 순서로 모든 객체를 포함 List<List<Object>>
하는로 변환 할 수 List<Object>
있습니까?
답변
당신이 사용할 수있는 flatMap
하나의 스트림에 (스트림으로 변환 후) 내부 목록을 평평하게 한 다음리스트로 결과를 수집 :
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
답변
flatmap
더 낫지 만 동일한 것을 달성하는 다른 방법이 있습니다
List<List<Object>> listOfList = ... // fill
List<Object> collect =
listOfList.stream()
.collect(ArrayList::new, List::addAll, List::addAll);
답변
이 flatMap
메소드 Stream
는 확실히 해당 목록을 평평하게 할 수 있지만 Stream
element에 대한 객체를 만든 다음 aStream
결과에 대한 .
모든 Stream
객체 가 필요하지는 않습니다 . 다음은 작업을 수행하는 간단하고 간결한 코드입니다.
// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);
는 List
is 이므로이 Iterable
코드 는에서 상속 된 메소드 (Java 8 기능)를 호출 합니다forEach
Iterable
.
Iterable
모든 요소가 처리되거나 작업에서 예외가 발생할 때까지 의 각 요소에 대해 지정된 작업을 수행합니다 . 해당 순서가 지정된 경우 반복 순서대로 조치가 수행됩니다.
그리고 List
의Iterator
순서대로 반환 항목.
의 경우 Consumer
,이 코드는 List.addAll
내부 목록 요소를 순차적으로 추가 하기 위해 메소드 참조 (Java 8 기능)를 Java 8 이전 메소드 로 전달합니다.
지정된 컬렉션의 모든 요소를 지정된 컬렉션의 반복자에 의해 반환되는 순서대로이 목록의 끝에 추가합니다 (선택적 작업).
답변
Eclipse Collections 의 flatCollect()
패턴을 사용할 수 있습니다 .
MutableList<List<Object>> list = Lists.mutable.empty();
MutableList<Object> flat = list.flatCollect(each -> each);
다음에서 목록을 변경할 수없는 경우 List
:
List<List<Object>> list = new ArrayList<>();
List<Object> flat = ListAdapter.adapt(list).flatCollect(each -> each);
참고 : 저는 Eclipse Collections에 기고자입니다.
답변
@Saravana가 언급 한 것처럼 :
플랫 맵이 더 좋지만 동일한 결과를 얻을 수있는 다른 방법이 있습니다
listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
요약하면 다음과 같이 여러 가지 방법으로 달성 할 수 있습니다.
private <T> List<T> mergeOne(Stream<List<T>> listStream) {
return listStream.flatMap(List::stream).collect(toList());
}
private <T> List<T> mergeTwo(Stream<List<T>> listStream) {
List<T> result = new ArrayList<>();
listStream.forEach(result::addAll);
return result;
}
private <T> List<T> mergeThree(Stream<List<T>> listStream) {
return listStream.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
});
}
private <T> List<T> mergeFour(Stream<List<T>> listStream) {
return listStream.reduce((l1, l2) -> {
List<T> l = new ArrayList<>(l1);
l.addAll(l2);
return l;
}).orElse(new ArrayList<>());
}
private <T> List<T> mergeFive(Stream<List<T>> listStream) {
return listStream.collect(ArrayList::new, List::addAll, List::addAll);
}
답변
같은 시나리오를 하나 더 설명하고 싶습니다 List<Documents>
.이 목록에는 List<Excel>
,, List<Word>
등 의 다른 문서 목록이 몇 개 더 List<PowerPoint>
있습니다. 그래서 구조는
class A {
List<Documents> documentList;
}
class Documents {
List<Excel> excels;
List<Word> words;
List<PowerPoint> ppt;
}
이제 문서에서만 Excel을 반복하려면 다음과 같이하십시오.
그래서 코드는
List<Documents> documentList = new A().getDocumentList();
//check documentList as not null
Optional<Excel> excelOptional = documentList.stream()
.map(doc -> doc.getExcel())
.flatMap(List::stream).findFirst();
if(excelOptional.isPresent()){
Excel exl = optionalExcel.get();
// now get the value what you want.
}
코딩하는 동안 누군가의 문제를 해결할 수 있기를 바랍니다.
답변
우리는 이것을 위해 flatmap을 사용할 수 있습니다. 아래 코드를 참조하십시오 :
List<Integer> i1= Arrays.asList(1, 2, 3, 4);
List<Integer> i2= Arrays.asList(5, 6, 7, 8);
List<List<Integer>> ii= Arrays.asList(i1, i2);
System.out.println("List<List<Integer>>"+ii);
List<Integer> flat=ii.stream().flatMap(l-> l.stream()).collect(Collectors.toList());
System.out.println("Flattened to List<Integer>"+flat);