스트림을 활용하면 배열, 컬렉션 등의 자료를 일관성 있게 처리할 수 있다. 자료에 따라 기능을 새로 구현하는 것이 아니라, 처리해야 하는 자료가 무엇인지와 상관없이 같은 방식으로 메소드를 호출할 수 있다.
Integer[] arr = {1,2,3,4,5,6,7,8,9,10};
List<Integer> sList = new ArrayList<>(Arrays.asList(arr));
//스트림생성, 중간연산, 최종연산
sList.stream().filter(s->s.intValue() >= 5).forEach(s -> System.out.println(s));
배열과 스트림 비교
int[] arr = {1,2,3,4,5};
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
// 스트림 생성, 요소를 하나씩 꺼내서 출력하는 기능
Arrays.stream(arr).forEach(n -> System.out.println(n));
public static void main(String[]args) {
// asList() : 일반 배열을 ArrayList 로 변경 한다.
ArrayList<String> list = new ArrayList<>(Arrays.asList("고유림", "나희도", "백이진"));
// Iterator 이용
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()) {
String name = iterator.next();
System.out.println(name);
}
System.out.println();
// Stream 이용
Stream<String> stream = list.stream();
stream.forEach(name -> System.out.println(name)); // 람다식
}
내부 반복자를 사용하므로 병렬 처리가 쉽다
public static void main(String[] args) {
List<String> list = Arrays.asList(
"나희도", "고유림", "백이진", "구자경", "우영우"
);
// 순차 처리
Stream<String> stream = list.stream();
stream.forEach(Main :: print);
System.out.println();
// 병렬 처리
Stream<String> parallelStream = list.parallelStream();
parallelStream.forEach(Main :: print);
System.out.println();
}
public static void print(String str) {
System.out.println(str + " : " + Thread.currentThread().getName());
}
중간처리와 최종처리를 할 수 있다
스트림은 컬렉션의 요소에 대해 중간 처리와 최종 처리를 수행 할 수 있는데, 중간 처리에서는 매핑, 필터링, 정렬을 수행하고 최종 처리에서는 반복, 카운팅, 평균, 총합 등의 집계 처리를 수행한다
public static void main(String[] args) {
List<Student> stList = Arrays.asList(
new Student("우영우", 99),
new Student("최수연", 96),
new Student("권민우", 92)
);
double avg = stList.stream()
// 중간처리 (스트림을 IntStream으로 변환)
.mapToInt(Student::getScore) // 메소드 참조
// 최종 처리
.average()
.getAsDouble();
System.out.println("평균 점수 : " + avg);
}
자바에서 제공하는 모든 컬렉션의 최고 상위 조상인 Collection 인터페이스에는 stream() 메소드 정의 되어 있습니다.
List<Integer> list = Arrays.asList(1,2,3,4,5);
Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);
배열에 관한 스트림을 생성하기 위해 Arrays 클래스에는 다양한 형태의 stream() 메소드가 클래스 메소드로 정의 되어 있습니다.
public static void main(String[] args) {
String[] arr = {"고유림", "나희도", "백이진", "구자경", "우영우"};
// 배열에서 스트림 생성
Stream<String> stream1 = Arrays.stream(arr);
stream1.forEach(e -> System.out.print(e + " "));
System.out.println();
// 배열의 특정 부분만을 이용한 스트림 생성
Stream<String> stream2 = Arrays.stream(arr, 1, 3);
stream2.forEach(e -> System.out.print(e + " "));
System.out.println();
}
1부터 100까지의 합을 구하기 위해 IntStream의 rangeClosed() 메소드를 이용
public static void main(String[] args) {
IntStream stream = IntStream.rangeClosed(1, 100);
stream.forEach(a -> sum += a);
System.out.println("총합 : " + sum);
}
Files의 정적 메소드인 lines()와 BufferedReader의 Line() 메소드를 이용하여 문자 파일의 내용을 스트림을 통해 행 단위로 읽고 콘솔에 출력 합니다.
public static void main(String[] args) throws IOException {
// 파일 내용을 소스로 하는 스트림
Path path = Paths.get("src/스트림파일/list.txt");
Stream<String> stream = Files.lines(path, Charset.defaultCharset());
stream.forEach(System.out::println);
System.out.println();
// BufferedReader의 Line() 메소드 이용
File file = path.toFile();
FileReader fileReader = new FileReader(file);
BufferedReader br = new BufferedReader(fileReader);
stream = br.lines();
stream.forEach(System.out::println);
}
Files의 정적 메소드인 list()를 이용해서 디렉토리의 내용을 스트림을 통해 읽고 콘솔로 출력 합니다.
public static void main(String[] args) throws IOException {
Path path = Paths.get("src");
Stream<Path> stream = Files.list(path);
stream.forEach(p->System.out.println(p.getFileName()));
}
count() 메소드는 해당 스트림의 요소의 총 개수를 long 타입의 값으로 반환합니다.
또한, max()와 min() 메소드를 사용하면 해당 스트림의 요소 중에서 가장 큰 값과 가장 작은 값을 가지는 요소를 참조하는 Optional 객체를 얻을 수 있습니다.
IntStream stream1 = IntStream.of(30, 90, 70, 10);
IntStream stream2 = IntStream.of(30, 90, 70, 10);
System.out.println(stream1.count());
System.out.println(stream2.max().getAsInt());
IntStream이나 DoubleStream과 같은 기본 타입 스트림에는 해당 스트림의 모든 요소에 대해 합과 평균을 구할 수 있는 sum()과 average() 메소드가 각각 정의되어 있습니다.
이때 average() 메소드는 각 기본 타입으로 래핑 된 Optional 객체를 반환합니다.
IntStream stream1 = IntStream.of(30, 90, 70, 10);
DoubleStream stream2 = DoubleStream.of(30.3, 90.9, 70.7, 10.1);
System.out.println(stream1.sum());
System.out.println(stream2.average().getAsDouble());