package ch17.sec01;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
// Set 컬렉션 생성 (파라미터를 문자열 형태로 사용!)
Set<String> set = new HashSet<>();
// Set 컬렉션에 문자열 추가
set.add("홍길동");
set.add("신용권");
set.add("감자바");
// Stream을 얻는 과정!
// Stream : set, list 등의 컬렉션을 스트림으로 변환하여 반복문 없이
// 데이터를 처리할 수 있게 해주는 역할을 함!
Stream<String> stream = set.stream();
// for(var name : set) {
// System.out.println(name);
// }
//
// 위의 for 구문과 비슷하다고 보면 됨!
// name : 향상된 for loop에서 인자라고 보면 됨!
// set 컬렉션으로 받은 스트림을 반복문 처리해준다고 보면됨!
// forEach : 향상된 for loop를 간단하게 표현했다고 보면 됨!
stream.forEach(name -> System.out.println(name));
}
}

package ch17.sec02;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class ParallelStreamExam {
public static void main(String[] args) {
// List 컬렉션 생성함 (파라미터값이 문자열!)
List<String> list = new ArrayList<>();
// List에 요소 추가!
list.add("홍길동");
list.add("신용권");
list.add("감자바");
list.add("람다식");
list.add("박병렬");
// 병렬 스트림 얻는 구문!
// 여러 개의 스레드를 사용하여 리스트의 데이터를 동시에 처리할 수 있도록 변환함
Stream<String> parallelStream = list.parallelStream();
// 리스트에 요소들을 하나씩 가져와서 해당 요소와 실행중인 스레드를 출력함
// 멀티스레드로 병렬처리를 하기 때문에 작업이 편해짐!
parallelStream.forEach(name -> {
System.out.println(name + ": " + Thread.currentThread().getName());
});
}
}


package ch17.sec03;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter // Getter 메소드 생성
@AllArgsConstructor // 모든 필드를 인자로 가지는 생성자 만듦
public class Student {
private String name;
private int score;
}
package ch17.sec03;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamPipeLineExample {
public static void main(String[] args) {
// Arrays.asList를 이용하여 배열로 값을 받고, List 컬렉션으로 변환함
List<Student> list = Arrays.asList(
new Student("홍길동", 10),
new Student("신용권", 20),
new Student("유미선", 30)
);
// list로 받은 값을 stream 형태로 변환하여 저장
// stream을 사용하면서 반복문 없이 데이터 처리하는데 용이해짐
Stream<Student> studentStream = list.stream();
// IntStream : int 값을 처리할 수 있는 스트림
// studentStream에서 받은 요소들 중에 int 타입의 요소들만 추출함
IntStream scoreStream = studentStream.mapToInt(
student -> student.getScore());
// scoreStream에서 받은 int 값의 평균을 구해서 double 형태로 변환
double avg = scoreStream.average().getAsDouble();
}
}


package ch17.sec04.exam01;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;
@Getter // getter 함수만 생성
@AllArgsConstructor // 모든 필드를 인자로 가지는 생성자
@ToString // toString 함수 생성
public class Product {
//필드 입력
private int pno;
private String name;
private String company;
private int price;
}
package ch17.sec04.exam01;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class StreamExam {
public static void main(String[] args) {
// List 컬렉션 생성
List<Product> list = new ArrayList<>();
for(int i=1;i<=5;i++) {
// Product 생성자에 인자 넣기!
Product product = new Product(1, "상품"+i, "멋진 회사",
(int)(10000*Math.random()));
list.add(product);
}
// List 컬렉션으로 받은 Product 객체의 요소들을 Stream 형태로 변환
Stream<Product> stream = list.stream();
// stream을 통해 Product에 저장된 요소들을 모두 출력함
stream.forEach(p -> System.out.println(p));
}
}
package ch17.sec04.exam02;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamExam {
public static void main(String[] args) {
// 문자열 배열 생성
String[] strArray = {"홍길동", "신용권", "김미나"};
// 배열을 Stream 형태로 변환하기
Stream<String> strStream = Arrays.stream(strArray);
// 문자열 배열을 하나씩 출력해줌
strStream.forEach(item -> System.out.print(item + ","));
System.out.println();
// 정수형 배열 생성
int[] intArray = {1, 2, 3, 4, 5};
// 정수형 배열을 stream 형태로 변환
// 기본형 타입의 경우 타입Stream 클래스명으로 선언!
IntStream intStream = Arrays.stream(intArray);
// 정수형 배열의 요소들을 하나씩 출력
intStream.forEach(item -> System.out.print(item + ","));
System.out.println();
}
}
package ch17.sec04.exam03;
import java.util.stream.IntStream;
public class StreamExam {
// 람다식에 적용하기 위해서는 정적 변수로 선언해줘야함
public static int sum;
public static void main(String[] args) {
// 1부터 100까지의 숫자 범위!
IntStream stream = IntStream.rangeClosed(1, 100);
// range(a,b) : a부터 b 바로 전의 수까지의 범위
// rangeClosed(a,b) : a부터 b까지의 범위
// 지역변수는 람다식에서 사용 못함
// int sum1 = 0;
// 1부터 100까지의 값을 모두 더함!
stream.forEach(a -> sum += a);
System.out.println("총합: " + sum);
}
}
package ch17.sec04.exam04;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) throws Exception {
// StreamExample.class : StreamExample 클래스를 참조한다는 뜻
// getResource("data.txt") : data.txt 파일을 찾음
// toURI() : getResource()는 URL 객체를 반환하는데 이를 URI 형태로 변환하는것
// URI 형태로 변환하는 이유 -> 웹 페이지에 국한된게 아닌 더 많은 종류의 파일을 찾기 위해서!
// Paths.get을 Path 객체의 형태로 변환 : 파일이나 디렉토리의 경로를 표현하는 클래스
Path path = Paths.get(StreamExample.class.getResource("data.txt").toURI());
// Path로 받은 경로의 파일을 인코딩하여 한 줄씩 읽어들임
Stream<String> stream = Files.lines(path, Charset.defaultCharset());
// 받아온 파일을 한 줄씩 출력함
stream.forEach(line -> System.out.println(line));
// stream 닫기
// 파일이나 네트워크같이 외부 자원을 사용하는 스트림은 시스템 리소스가
// 반납되지 않을 수도 있기 때문에 close를 통해 자원을 명시적으로 해제해줘야함
stream.close();
}
}





package ch17.sec05;
import java.util.ArrayList;
import java.util.List;
public class FilteringExample {
public static void main(String[] args) {
// List 컬렉션 생성, ArrayList 사용
List<String> list = new ArrayList<>();
// List 컬렉션에 요소 추가 (문자열)
list.add("이동주");
list.add("홍길동");
list.add("이동주");
list.add("감자바");
list.add("이진아");
// 중복 제거
// list.stream() : 스트림을 사용하여 컬렉션의 데이터를 처리!
list.stream()
// distinct() : 중복 제거
.distinct()
// forEach() : 값을 차례대로 출력
.forEach(n -> System.out.println(n));
System.out.println();
// 성이 "이"로 시작하는 사람 출력
list.stream()
// filter() : 요소를 거르는 역할로, 조건문 역할을 함
.filter(n -> n.startsWith("이"))
.forEach(n -> System.out.println(n));
System.out.println();
// 성이 "이"로 시작하는 사람을 출력하고, 중복 제거 실시
list.stream()
.distinct()
.filter(n -> n.startsWith("이"))
.forEach(n -> System.out.println(n));
}
}




package ch17.sec06.exam01;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter // getter 사용
@AllArgsConstructor // 모든 필드를 매개변수로 가지는 생성자
public class Student {
private String name;
private int score;
}
package ch17.sec06.exam01;
import java.util.ArrayList;
import java.util.List;
public class MapExample {
public static void main(String[] args) {
// List 컬렉션 생성
List<Student> studentList = new ArrayList<>();
// List 컬렉션에 요소를 추가
studentList.add(new Student("이동주", 95));
studentList.add(new Student("이진아", 97));
studentList.add(new Student("홍길동", 50));
// Student 객체를 stream으로 변환
studentList.stream()
// Student 객체에 받은 값중에 int 타입의 요소만을 받기
.mapToInt(s -> s.getScore())
// 위의 조건으로 받은 요소들을 모두 출력
.forEach(score -> System.out.println(score));
}
}

package ch17.sec06.exam02;
import java.util.Arrays;
import java.util.stream.IntStream;
public class MapExample {
public static void main(String[] args) {
int[] intArray = {1, 2, 3, 4, 5};
// intArray를 int 타입으로 반복 처리
IntStream intStream = Arrays.stream(intArray);
intStream
// int 형태로 처리한 Stream을 double 타입으로 변환하여 stream 처리
.asDoubleStream()
// forEach : 하나씩 값을 가져오는 역할!
.forEach(d -> System.out.println(d));
System.out.println();
intStream = Arrays.stream(intArray);
intStream
// boxed() : 기본형 스트림을 래퍼 클래스 (Integer, Double 등 클래스)의 스트림으로 변환
// 래퍼 클래스로 변환함으로써 컬렉터나 제네릭을 활용할 수 있음
.boxed()
// Integer 타입의 값들을 int 타입으로 변환해서 하나씩 출력함
.forEach(obj -> System.out.println(obj.intValue()));
}
}


package ch17.sec06.exam03;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FlatMappingExample {
public static void main(String[] args) {
// ArrayList 사용
// 문장 스트림을 단어 스트림으로 변환함
List<String> list1 = new ArrayList<>();
list1.add("this is java");
list1.add("i am a best developer");
list1.stream()
// flapMap : 여러 개의 스트림을 변환하여 하나의 스트림의 형태로 만듬!
// Arrays.stream -> 배열을 스트림 형태로 변환하는 역할을 함!
// split : 해당 문자를 기준으로 문자열을 나눔
.flatMap(data -> Arrays.stream(data.split(" ")))
.forEach(word -> System.out.println(word));
// 문자열 숫자 목록 스트림을 숫자 스트림으로 변환함
List<String> list2 = Arrays.asList("10, 20, 30, 40, 50");
list2.stream()
// String 형태의 스트림을 int 형태의 스트림으로 변환함
.flatMapToInt(data -> {
// 쉼표로 문자열을 나눔
String[] strArr = data.split(",");
// list에서 나눠진 문자들의 갯수만큼 int 배열 생성
int[] intArr = new int[strArr.length];
// 문자열의 앞뒤 공백을 제거하여 정수 형태로 변환 후 int 배열에 값을 하나씩 저장
for(int i=0;i<strArr.length;i++) {
intArr[i] = Integer.parseInt(strArr[i].trim());
}
// 위 int 배열을 스트림형태로 변환
return Arrays.stream(intArr);
})
// 위 스트림에 있는 값들을 하나씩 출력!
.forEach(number -> System.out.println(number));
}
}

package ch17.sec07.exam01;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
// Comparable<T> : 클래스 내에서 값을 비교하기 위해 사용!
public class Student implements Comparable<Student> {
private String name;
private int score;
@Override
public int compareTo(Student o) {
// 두 수가 같으면 0, 작으면 음수, 클경우 양수를 리턴함
return Integer.compare(score, o.score);
}
}
package ch17.sec07.exam01;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class SortingExample {
public static void main(String[] args) {
// ArrayList 사용
List<Student> studentList = new ArrayList<>();
// List에 요소를 추가함
studentList.add(new Student("홍길동", 30));
studentList.add(new Student("이동주", 10));
studentList.add(new Student("감자바", 20));
studentList.stream()
// sorted() : 점수(정수 타입의 값)를 기준으로 오름차순 정렬
.sorted()
// 이름과 점수를 순차적으로 출력함
.forEach(s -> System.out.println(s.getName() + ": " + s.getScore()));
System.out.println();
studentList.stream()
// Comparator.reverseOrder() : 점수(정수 타입의 값 기준으로 내림차순 정렬
.sorted(Comparator.reverseOrder())
.forEach(s -> System.out.println(s.getName() + ": " + s.getScore()));
}
}
sorted((o1, o2) -> { ... })
요소 객체가 Comparable을 구현하고 있지 않다면, 비교자를 제공하면 요소를 정렬시킬 수 있음
괄호 안에는 o1이 o2보다 작으면 음수, 같으면 0, 크면 양수를 리턴하도록 작성
Integer.compare(o1, o2) : o1, o2가 정수일 때 호출
Double.compare(o1, o2) : o1, o2가 실수일 때 호출
package ch17.sec07.exam02;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public class Student {
private String name;
private int score;
}
package ch17.sec07.exam02;
import java.util.ArrayList;
import java.util.List;
public class SortingExample {
public static void main(String[] args) {
// ArrayList 사용
List<Student> studentList = new ArrayList<>();
// List에 요소 추가
studentList.add(new Student("홍길동", 30));
studentList.add(new Student("이동주", 10));
studentList.add(new Student("감자바", 20));
studentList.stream()
// score를 기준으로 오름차순 정렬
.sorted((s1, s2) -> Integer.compare(s1.getScore(), s2.getScore()))
.forEach(s -> System.out.println(s.getName() + ": " + s.getScore()));
studentList.stream()
// s2와 s1의 순서를 바꿔 score를 기준으로 내림차순 정렬
.sorted((s1, s2) -> Integer.compare(s2.getScore(), s1.getScore()))
.forEach(s -> System.out.println(s.getName() + ": " + s.getScore()));
}
}





1) isPresent() 메소드가 true를 리턴할 때만 집계값을 얻는다
2) orElse() 메소드로 집계값이 없을 경우를 대비해서 디폴트 값을 정해놓는다
3) ifPresent() 메소드로 집계값이 있을 경우에만 동작하는 Consumer 람다식을 제공함






