>source

저는 Java 초보자입니다. mapflatMap .

2d List를 1d List로 변환해야하는 경우 아래와 같이 구현되었습니다.

List<List<Integer>> list_2d = List.of(List.of(1, 2), List.of(3, 4));
List<Integer> lst1 = list_2d
    .stream()
    .flatMap(arr -> arr.stream())
    .collect(Collectors.toList());
printAll(lst1); // [1, 2, 3, 4]

그러나 사용하지 않고 구현할 수 있다고 생각합니다. flatMap .

동일한 논리로 코드를 만들 수있는 방법이 있습니까? map , 사용하지 않음 flatMap ?

왜냐하면 map 모두를 대체 할 수 있습니다 flatMap , 외울 이유가 없습니다 flatMap . 저는 항상 단순하고 기본적인 것을 추구합니다.

  • 답변 # 1

    질문에 답하기 위해 다른 방법이 있지만 생각할 수있는 방법은 추천하지 않습니다. 예를 들어 감소를 사용할 수 있습니다.

       List<List<Integer>> list2d = List.of(List.of(1, 2), List.of(3, 4));
        List<Integer> lst1 = list2d
            .stream()
            .reduce((l1, l2) -> {
                ArrayList<Integer> concatenated = new ArrayList<>(l1);
                concatenated.addAll(l2);
                return concatenated;
            })
            .orElse(List.of()); // or else empty list
        
        System.out.println(lst1);
    
    

    출력은 당신과 동일합니다.

    [1, 2, 3, 4]

    그러나 귀하의 코드는 내 것보다 훨씬 이해하기 쉽습니다. 나는 당신이 그것에 충실하는 것이 좋습니다.

    Just because, if map can replaced all of flatMap, there are no reason to memorize flatMap. I always pursue simple and basic thing.

    당신은 이미 가장 간단하고 가장 기본적인 것을 얻었습니다. 또한 스트림에서 최대한의 잠재력을 얻으려면 가끔 사용해야하는 메서드 호출이 많이 있습니다. 수년 동안 스트림을 사용한 후에도 가끔 Javadoc에서 스트림을 찾고 있습니다. 나는 세부 사항을 찾아야했다 reduce() 이 대답을 위해. 머릿속에 모든 것이있을 것이라고 기대하지 마십시오. 알아 flatMap() 그러나 그것은 종종 실용적이기 때문입니다.

  • 답변 # 2

    이것은 당신이 찾고있는 것이 아닐 수도 있지만 목표가 모든 하위 목록을 하나의 결과 목록에 추가하는 것이라면 for each를 사용하는 것도 측면에서 옵션이 될 수 있습니다.간단하고 기본적인:

    List<List<Integer>> list_2d = List.of(List.of(1, 2), List.of(3, 4));
    List<Integer> result = new ArrayList<>();
    list_2d.forEach(list -> result.addAll(list));
    System.out.println(result);
    
    

  • 답변 # 3

    당신은 제거 할 수 있습니다 flatMap 평면 매핑을 수행하는 경우 collect :

    List<Integer> lst1 = list_2d
        .stream()
        .collect(Collectors.flatMapping (List::stream, Collectors.toList()));
    
    

    그러나 나는 사용의 이점을 보지 못합니다. Collectors.flatMapping 대신에 flatMap .

  • 답변 # 4

    이미 다른 구현을 제공하는 여러 답변이 있으므로 차이점을 보여 드리겠습니다. mapflatMap .

    그만큼 map 연산은 스트림의 모든 요소를 ​​정확히 하나의 다른 요소로 변경하는 데 사용됩니다. 귀하의 예에서 가능한 사용 사례는 목록에서 일부 집계 (예 : 모든 요소 합계)를 수행하여 List<Integer> 개별 목록의 모든 합계를 포함합니다. 또는 데이터 구조를 세트로 변경하여 List<Set<Integer>> . 결과 목록의 요소 수는 원래 목록에 2 개의 요소가 있으므로 항상 2 개입니다.

    그만큼 flatMap 반면에 연산은 하나의 요소를 0 개 이상의 요소로 변환하는 데 사용됩니다. 다수의 인간으로 구성된 클래스 패밀리를 고려하십시오. 어딘가에서 가족 목록을 얻었지만 개별 사람들에 대해서만 관심이 있다면 flatMap 가족 목록을 인간 목록에 추가합니다.

    차이점 flatMap 다른 답변에 제공된 구현은 작업 유형입니다. flatMap 중간 작업이며 결과는 Stream . collectreduce 결과가 다른 것을 의미합니다 (귀하의 예에서 : a List<Integer> . 더 많은 스트림 작업을 수행하려는 경우 (예 : filter 또는 다른 map ) 다른 하나를 만들어야합니다. Stream 결과 목록의.

    이를 설명하기 위해 질문에 주어진 목록을 고려하여 결과적으로 목록의 모든 짝수를 원합니다. 나는 collect 이 답변의 해결책. 보시다시피 flatMap 불필요한 List 생성과 일부 코드 라인을 절약합니다.

    public static void usingFlatMap() {
        List<List<Integer>> originalList = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));
        List<Integer> result = originalList
                .stream()
                .flatMap(list -> list.stream())
                .filter(number -> number % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(result); // [2, 4]
    }
    public static void usingCollect() {
        List<List<Integer>> originalList = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4));
        List<Integer> intermediateList = originalList
                .stream()
                .collect(Collectors.flatMapping(List::stream, Collectors.toList()));
        List<Integer> result = intermediateList
                .stream()
                .filter(number -> number % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(result); // [2, 4]
    }
    
    

관련 자료

  • 이전 모든 객체가 단일 배열로 푸시되는 대신 개별 배열로 푸시 된 자바 스크립트 객체를 해결하는 방법은 무엇입니까?
  • 다음 python - 데이터 탐색 코딩에서 UnboundLocalError 가져 오기