programing

Java 8에서 목록 목록을 목록으로 변환하려면 어떻게 해야 합니까?

firstcheck 2022. 8. 15. 10:58
반응형

Java 8에서 목록 목록을 목록으로 변환하려면 어떻게 해야 합니까?

만약 내가 가지고 있다면List<List<Object>>어떻게 하면 이 모든 것을List<Object>Java 8의 기능을 사용하여 동일한 반복 순서로 모든 오브젝트를 포함합니까?

를 사용하여 (Streams로 변환한 후) 내부 목록을 단일 스트림으로 평탄화하고 결과를 목록으로 수집할 수 있습니다.

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요소에 대한 객체, 그 다음Stream결과를 위해.

그런 거 다 필요없어Stream물건들.다음은 작업을 수행하기 위한 단순하고 간결한 코드입니다.

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

왜냐하면...ListIterable이 코드는 메서드(Java 8 기능)를 호출하여 에서 상속됩니다.Iterable.

각 요소에 대해 지정된 액션을 수행합니다.Iterable모든 요소가 처리되거나 작업이 예외를 발생시킬 때까지 계속됩니다.액션은 반복 순서가 지정되어 있는 경우 반복 순서로 수행됩니다.

그리고...ListIterator항목을 순서대로 반환합니다.

를 위해Consumer이 코드는 메서드레퍼런스(Java 8 기능)에서 Java 8 이전의 메서드로 전달되어 내부 리스트 요소를 순차적으로 추가합니다.

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

변환 방법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]

Python에서는 List Concription을 사용하여 이를 수행할 수 있습니다.

list_of_lists = [['Roopa','Roopi','Tabu', 'Soudipta'],[180.0, 1231, 2112, 3112], [130], [158.2], [220.2]]

flatten = [val for sublist in list_of_lists for val in sublist]

print(flatten)
['Roopa', 'Roopi', 'Tabu', 'Soudipta', 180.0, 1231, 2112, 3112, 130, 158.2, 220.2]

@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.
 }

이걸로 코딩하는 동안 누군가의 문제가 해결됐으면 좋겠는데...

를 사용할 수 있습니다.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);

주의: 저는 이클립스 컬렉션에 기고하고 있습니다.

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 문이 있는 것과 유사합니다.

Stream#mapMulti

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .collect(Collectors.toList());

의 것이 List도 할 수 있어요.toList()

List<Object> result = listOfLists.stream()
                                 .mapMulti((List<Object> list, Consumer<Object> consumer) -> {
                                     list.forEach(consumer::accept);
                                 })
                                 .toList();

이를 위해 플랫맵을 사용할 수 있습니다.아래 코드를 참조하십시오.

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

목록 <목록> 목록 = map.values().stream().collectors.toList();

    List<Employee> employees2 = new ArrayList<>();
    
     list.stream().forEach(
             
             n-> employees2.addAll(n));

언급URL : https://stackoverflow.com/questions/25147094/how-can-i-turn-a-list-of-lists-into-a-list-in-java-8

반응형