답변:
당신이 사용할 수있는 flatMap
하나의 스트림에 (스트림으로 변환 후) 내부 목록을 평평하게 한 다음리스트로 결과를 수집 :
List<List<Object>> list = ...
List<Object> flat =
list.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
Class::method
처음에는 조금 이상하게 느껴지지만 어떤 종류의 객체를 매핑하는지 선언하는 이점이 있습니다. 그것은 스트림에서 다른 방법으로 잃어버린 것입니다.
이 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);
Eran의 대답에 대한 확장은 최고의 대답이었습니다. 목록의 계층이 많은 경우 계속 매핑 할 수 있습니다.
필요한 경우 레이어를 내려 가면서 편리한 필터링 방법도 제공됩니다.
예를 들어 :
List<List<List<List<List<List<Object>>>>>> multiLayeredList = ...
List<Object> objectList = multiLayeredList
.stream()
.flatmap(someList1 -> someList1
.stream()
.filter(...Optional...))
.flatmap(someList2 -> someList2
.stream()
.filter(...Optional...))
.flatmap(someList3 -> someList3
.stream()
.filter(...Optional...))
...
.collect(Collectors.toList())
이것은 SQL에서 SELECT 문 내에 SELECT 문을 갖는 것과 유사합니다.
메소드를 변환 List<List>
합니다 List
:
listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
이 예제를보십시오 :
public class Example {
public static void main(String[] args) {
List<List<String>> listOfLists = Collections.singletonList(Arrays.asList("a", "b", "v"));
List<String> list = listOfLists.stream().flatMap(List::stream).collect(Collectors.toList());
System.out.println("listOfLists => " + listOfLists);
System.out.println("list => " + list);
}
}
다음을 인쇄합니다.
listOfLists => [[a, b, c]]
list => [a, b, c]
::
:)