[java] Java 8에서 List List를 List로 바꾸려면 어떻게해야합니까?

내가있는 경우 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는 확실히 해당 목록을 평평하게 할 수 있지만 Streamelement에 대한 객체를 만든 다음 aStream 결과에 대한 .

모든 Stream객체 가 필요하지는 않습니다 . 다음은 작업을 수행하는 간단하고 간결한 코드입니다.

// listOfLists is a List<List<Object>>.
List<Object> result = new ArrayList<>();
listOfLists.forEach(result::addAll);

Listis 이므로이 Iterable코드 는에서 상속 된 메소드 (Java 8 기능)를 호출 합니다forEachIterable .

Iterable모든 요소가 처리되거나 작업에서 예외가 발생할 때까지 의 각 요소에 대해 지정된 작업을 수행합니다 . 해당 순서가 지정된 경우 반복 순서대로 조치가 수행됩니다.

그리고 ListIterator 순서대로 반환 항목.

의 경우 Consumer,이 코드는 List.addAll내부 목록 요소를 순차적으로 추가 하기 위해 메소드 참조 (Java 8 기능)를 Java 8 이전 메소드 로 전달합니다.

지정된 컬렉션의 모든 요소를 ​​지정된 컬렉션의 반복자에 의해 반환되는 순서대로이 목록의 끝에 추가합니다 (선택적 작업).


답변

Eclipse CollectionsflatCollect()패턴을 사용할 수 있습니다 .

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);