Closed JinseoPark-bd closed 1 year ago
예를 들어 색깔별로 2개씩 분류한 과일의 String[][] 타입의 2차원 배열이 있다고 가정한다면 이때 Apple인 것만 제외하고 새로운 String[] 타입을 얻는 요구사항을 가장 간단하게 구현하는 방법은 아래와 같습니다.
@Test
public void 이차원_배열을_중첩for문으로_접근하기() {
String[][] nested = new String[][]{ {"Apple", "Cherry"}, {"Mango", "Orange"}, {"Grape", "BlueBerry"}};
List<String> fruits = new ArrayList<>();
for (String[] fs : nested) {
for (String f : fs) {
if(!f.equals("Apple")) fruits.add(f);
}
}
String[] exclude = fruits.toArray(new String[fruits.size()]);
System.out.println(Arrays.toString(exclude));
}
결과 ) [Cherry, Mango, Orange, Grape, BlueBerry]
위 실행 결과를 Stream의 filter() 메서드만 활용해서 최대한 비슷하게 구현하면 아래와 같습니다.
@Test
public void 이차원_배열을_flatMap없이_접근하기() {
String[][] nested = new String[][]{ {"Apple", "Cherry"}, {"Mango", "Orange"}, {"Grape", "BlueBerry"}};
List<String[]> fruits = Arrays.stream(nested)
.filter(fs -> { //<- nested가 2차원 배열이기 때문에 넘어오는 fs 변수는 1차원 배열 String[]
for (String f : fs) { //<- fs가 1차원 배열이기 때문에 다시 순회하기 위해 for문 적용
if (f.equals("Apple")) return false;
}
return true;
})
.collect(Collectors.toList()); //<- 결과적으로 filter()가 리턴하는 타입은 Stream<String[]> 이기 때문에 List<String>타입으로 가져올 수 없고 List<String[]> 타입으로 collecting
fruits.forEach(fs-> System.out.println(Arrays.toString(fs)));
}
코드에서 설명한대로 2차원배열-> 1차원배열 -> 개별요소로 접근해야하므로 코드의 가독성이 안 좋아지고 우리가 원하는 List
결과 ) [Mango, Orange] [Grape, BlueBerry]
단순히 Apple값을 제외하려고 했지만 Apple과 같은 배열에 있는 Cherry 역시 제거된 상태가 되는데 위에서 설명한 fs 변수가 개별요소가 아닌 1차원 배열이기 때문에 Apple 이 포함된 [Apple, Cherry] 배열 자체를 필터링 시킨 결과가 나오게 됩니다.
이때 flatMap()을 활용하면 쉽게 접근할 수 있습니다.
@Test
public void 이차원_배열을_flatMap으로_접근하기() {
String[][] nested = new String[][]{ {"Apple", "Cherry"}, {"Mango", "Orange"}, {"Grape", "BlueBerry"}};
List<String> fruits = Arrays.stream(nested)
.flatMap(fs -> Arrays.stream(fs)) //<- Stream 타입을 리턴
.filter(f -> !f.equals("Apple"))
.collect(Collectors.toList());
fruits.forEach(System.out::println);
}
결과 ) Cherry Mango Orange Grape BlueBerry
참고 ) https://sup2is.github.io/2021/01/19/flatmap-example.html
p163 ~ p165 두 단어에서 중복된 문자를 제거하여 하나의 문자열로 반환하는 문제입니다.