반응형
stream API
public class ForIterationExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
for (int i = 0; i < integerList.size(); i++) {
System.out.println(integerList.get(i));
}
}
}
-> stream API 를 사용하지 않을 때. for 의 iterator 를 사용할 때
- 기존의 for, if 문을 대체할 수 있다.
- for 와 달리 forEach 를 쓰기때문에, 인덱스를 알 수 없다. (사실 알게할 수는 있는데, 가독성이 매우 떨어지게된다.)
- for 와 달리 break 가 없다. (filter() 를 사용하면 break 가능)
- Collection 인터페이스를 상속받은 클래스들에서 stream 을 사용 가능하다. (ArrayList, HashSet, etc)
- Map 인터페이스를 상속받은 클래스들에서는 우회해서 사용 가능하다.(HashMap, etc)
forEach - 반복시키기
public class ForEachIterationExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
integerList.stream().forEach(integer -> {
System.out.println(integer);
if(integer.equals(40)) {
throw new RuntimeException();
}
});
}
}
filter - 조건에 맞는 요소만 뽑기
public class ForAndIfFilterExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
Integer findNumber = null;
for (int i = 0; i < integerList.size(); i++) {
System.out.println(integerList.get(i));
if(integerList.get(i).equals(40)) {
findNumber = integerList.get(i);
break;
}
}
System.out.println("findNumber=" + findNumber);
}
}
-> for 에서 조건에 맞는 분기를 if 로 찾고있다.
public class FilterExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
Integer findNumber = integerList.stream().filter(integer -> {
System.out.println(integer);
if(integer.equals(40))
return true;
return false;
}).findAny().get();
System.out.println("findNumber=" + findNumber);
}
}
-> 조건에 맞지 않는 분기는 return false 한다.
-> filter 에서 조건에 맞는 분기는 return true 하고 있다.
-> .findAny() 해서 하나를 찾자마자 filter 가 종료된다. (for 에서 break 와 같은 효과)
map - 요소를 매핑시키기
interface 의 map 이 아니다. stream API 의 map 메서드를 말한다.
map 메서드는 원래의 Collection 에서 특정한 연산을 적용하여 새로운 Collection 을 만든다.
public class ForMapExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
List<Integer> x10IntegerList = new ArrayList<>();
for (int i = 0; i < integerList.size(); i++) {
x10IntegerList.add(integerList.get(i) * 10);
}
System.out.println(x10IntegerList);
}
}
public class MapExampleMain {
public static void main(String[] args) {
List<Integer> integerList = new ArrayList<>();
integerList.add(10);
integerList.add(20);
integerList.add(30);
integerList.add(40);
integerList.add(50);
integerList.add(60);
integerList.add(70);
List<Integer> x10IntegerList = integerList.stream()
.map(integer -> integer * 10)
.toList();
System.out.println(x10IntegerList);
}
}
위 두 코드는 정확하게 같은 동작을 한다.
map() 에서는 람다식을 파라미터로 전달받는데, 1 line 짜리 람다식은 중괄호가 {} 생략 가능하다.
filter와 map의 결합
public class FilterAndMapExampleMain {
public static void main(String[] args) {
int[] integerArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> integerList = Arrays.stream(integerArray)
.boxed()
.toList();
System.out.println(integerList);
List<Integer> evenNumberList = integerList.stream()
.filter(integer -> integer % 2 == 0)
.toList();
System.out.println(evenNumberList);
List<Integer> evenX10NumberList = evenNumberList.stream()
.map(integer -> integer * 10)
.toList();
System.out.println(evenX10NumberList);
}
}
-> list 에서 짝수만 뽑아와서 데이터를 모두 10배씩 해서 새로운 list 를 만드는 과정
List<Integer> evenX10NumberList = integerList.stream()
.filter(integer -> integer % 2 == 0)
.map(integer -> integer * 10)
.toList();
-> 이렇게 filter() 와 map() 을 합칠 수 있다.
for + if 의 조합에 비해서 가독성이 얼마나 좋은가!
stream 을 잘 다루는 것은 자바 개발자에게 엄청난 무기가 되겠다.
map 에 stream API 사용하기
앞에서 말했던 것처럼 map 은 Collection 인터페이스를 상속받지 않고,
독자적인 인터페이스를 상속받기 때문에 stream API 를 사용할 수 없다.
하지만 map 을 set 으로 변환시켜서 stream API 를 사용할 수 있다.
public class MapStreamExample {
public static void main(String[] args) {
Map<String, Integer> someMap = new HashMap<>();
Set<Map.Entry<String, Integer>> entries = someMap.entrySet();
Set<String> keySet = someMap.keySet();
List<Integer> valueList = someMap.values().stream().toList();
entries.stream().forEach(stringIntegerEntry -> {
String key = stringIntegerEntry.getKey();
Integer value = stringIntegerEntry.getValue();
// key, value 사용
});
}
}
반응형
'백엔드 데브코스' 카테고리의 다른 글
[Java] 의존 관계란? (0) | 2023.09.26 |
---|---|
[Java] stream API 와 Optional (0) | 2023.09.26 |
[Java] getter, setter, 생성자로 알아보는 객체지향적인 코드 (0) | 2023.09.25 |
[Java] if문 제거하기 - 리팩토링 (0) | 2023.09.25 |
[Java] Optional - nullPointException을 잘 다뤄보자 (0) | 2023.09.25 |