Java공부(코딩)

자바/스프링 부트캠프 20일차 (스트림)

동곤일상 2025. 2. 27. 15:52
반응형

 

1) 스트림

1-1) map함수 예제

 

1-2 ) flatMap

 

1-3) Stream Sorted (스트림정렬)

 

1-4) peek , forEach

 

1-5) Sequencial  ,  Parallel

  (순차   , 병렬)

 

1-6) Consumer AndThen

 

1-7) Function   andThen()  , compose()

 

 


@@ 1) 스트림 @@

1-1) @@ map함수를 이용한 예제 @@

 

파일의내용

(파일을 한줄 씩 가져와야할 것같다

BufferReader사용하자)

Car클래스

class Car{
	private int month;
	private int con;
	private String car;
	private int qty;
	private String remark;
	public Car(int month, int con, String car, int qty, String remark) {
		super();
		this.month = month;
		this.con = con;
		this.car = car;
		this.qty = qty;
		this.remark = remark;
	}
	public int getMonth() {
		return month;
	}
	public int getCon() {
		return con;
	}
	public String getCar() {
		return car;
	}
	public int getQty() {
		return qty;
	}
	public String getRemark() {
		return remark;
	}
	@Override
	public String toString() {
		return  "["+month + ", con=" + con + ", car=" + car + ", qty=" + qty + ", remark=" + remark + "]";
	}

}

 

구동클래스

package ex4_map;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.stream.Stream;

/*
 * product.txt 파일생성
 */


public class MapEx2_product {

	static String carName = "BMW";
	static int con = 1;

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new FileReader("product.txt"));
		//br.lines 텍스트파일의 내용을 한줄 씩 Stream으로 생성 . 파일에서Stream객체로생성
		//Stream<String> br.lines()
		//한개의 요소 : 4 , 3 , BMW , 4 , 몰라요
		/*
		 * month 필드 : 4
		 * con필드  :  3 --> 1:생산 2:판매 3:반품
		 * car 필드 : BMW -> 자동차 이름
		 * qty 필드 : 4--> 수량
		 * remark 필드 : 몰라요 -> 반품사유
		 * 
		 * br.liines().map(Function String Car)=>
		 * 		Stream<String> --> Stream<Car> 변경
		 * 	
		 */
		Stream<Car> carStream = br.lines().map(s->{              //  0   1   2    3     4 
			String[] str  = s.split(",");//["4","3","BMW","4","몰라요"]
			String temp = "";
			try {
				temp = str[4];//반퓸사유 저장
			}
			catch(ArrayIndexOutOfBoundsException e) {
				//str[4]가 존재하지않는다면 temp에 빈 문자열 전달!!
				temp="";
			}
			return new Car(Integer.parseInt(str[0]), 
					Integer.parseInt(str[1]),
								str[2],//String
					Integer.parseInt(str[3]), 
								temp);//String
		});//Stream<Car> 변경
		
		carStream.filter(s->s.getCar().equals(carName)&&s.getCon()==con)
		//filter로 새로만든Car객체와 조건을 비교한다.) true인 경우에만 넘김
				.forEach(s->System.out.println(s));
					//true인 객체만 출력
	}
}

사용한 함수 )

Buffer.lines() : 읽어온 텍스트파일을 한줄씩 Stream으로변경

 

Stream.map(Function String Car)=>
  Stream<String> --> Stream<Car> 변경 

 

 filter(Predicate p)   : p에 조건을 걸어서 조건에맞는객체만 통과시킴

 

forEach : 객체를 모두 순회

[7, con=1, car=BMW, qty=5, remark=]

[10, con=1, car=BMW, qty=3, remark=]

[1, con=1, car=BMW, qty=2, remark=]

[1, con=1, car=BMW, qty=5, remark=]

[2, con=1, car=BMW, qty=4, remark=]

[9, con=1, car=BMW, qty=3, remark=]

 


 

예제 2) 위 파일에서 그랜져의 반품목록,수량을 싹다 가져와라

반품코드 con==3

package ex4_map;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.function.Function;
import java.util.stream.Stream;

/*
 * product.txt 파일에서 그랜져 반품목록 출력하기
 */
public class Exam2 {
	public static void main(String[] args) throws IOException {
		BufferedReader br  = new BufferedReader(new FileReader("product.txt"));
		
		Function<String, Car> f = s->{
			//람다식 활용
			String[] split = s.split(",");
			String remark = "";
			
			try {
				remark = split[4];
				
			} catch (Exception e) {
				remark = "";
			}
			return new Car(Integer.parseInt(split[0]), 
					Integer.parseInt(split[1]),
					split[2], 
					Integer.parseInt(split[3]),
					remark);
		};
		
		br.lines().map(f).filter(s->s.getCar().equals("그랜저")&&s.getCon()==3)
		//carStream에  다음과같은 필터를 씌운다.
		.forEach(s->System.out.println(s));
		//필터가 True인 객체만 출력
		
		//그랜저의 반품수량출력
		//한번 순회하면 스트림이 사라지기때문에 다시생성해야함!!
		br  = new BufferedReader(new FileReader("product.txt"));
		int sum = br.lines().map(f).filter(s->s.getCar().equals("그랜저")&&
				s.getCon()==3).mapToInt(s->s.getQty()).sum();
		System.out.println("그랜저 반품 수량 :"+sum);
	}
}

스트림은 한번 순회하면 사라지는 일회용임!!!

[5, con=3, car=그랜저, qty=4, remark=그냥이요]

[12, con=3, car=그랜저, qty=2, remark=그냥이요]

[5, con=3, car=그랜저, qty=4, remark=싫어요]

[4, con=3, car=그랜저, qty=2, remark=그냥이요]

[7, con=3, car=그랜저, qty=5, remark=그냥이요]

[9, con=3, car=그랜저, qty=3, remark=몰라요]

[1, con=3, car=그랜저, qty=5, remark=그냥이요]

[1, con=3, car=그랜저, qty=5, remark=그냥이요]

[9, con=3, car=그랜저, qty=5, remark=몰라요]

그랜저 반품 수량 :35

 

 


1-2)  @@ FlatMap @@



 * flatMap 함수 : 다른형태의 요소로 새로운 스트림을 생성
 * 
 * Stream<R> flatMap(Function<T,Stream<R>>) : 
 * T를 입력받아 Stream<R>로반환
 * 
 * DoubleStream flatMap(DoubleFunction<DoubleStream>) : 
 * double형을 매개변수로입력받아 DoubleStream 으로리턴
 * 
 * IntStream flatMap(IntFunction<IntStream>) : 
 * int형 매개변수로 입력받아 IntStream으로 리턴
 * 
 * IntStream flatMapToInt(Function<T,IntStream>) : 
 * T를 매개변수로 입력받아 IntStream으로 리턴

package ex5_flatmap;

import java.util.Arrays;
import java.util.List;

public class FlatMapEx1 {
	public static void main(String[] args) {
		List<String> list = Arrays.asList("자바 8 버전에","추가된 스트림을","열심히 공부하자");
		list.stream()//3개의문자열 요소를 Stream<String> 생성
		//data.split(" "); data값을 공백을 기준으로 문자열배열로리턴 (String[])
		//Arrays.stream(data.split(" ")) : 문자배열--> Stream<String>
		//flatMap : Stream<String> 요소 3개 --> Stream<String>요소 7개
		.flatMap(data->Arrays.stream(data.split(" ")))
		.forEach(word->System.out.println(word));
	}
}

자바

8

버전에

추가된

스트림을

열심히

공부하자

 


flatMap 예제 1

 

package ex5_flatmap;

import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/*
 * IntStream flatMapToInt() : Stream을 IntStream 으로 변경
 * 
 *
 */
public class FlatMapEx2 {
	public static void main(String[] args) {
		List<String> list = Arrays.asList("10,20,30,a","40,50,60");
		//list를 IntStream으로변경하기
		
		//flatMaptoInt의 api를 확인해보면 <? super String , IntStream>을 확인가능
		Function<String, IntStream> f= data->{
			 String[] strArr = data.split(",");
			 int[] intArr = new int[strArr.length];//int형 배열 생성
			 for (int i = 0; i < strArr.length; i++) {
				 try {
				 intArr[i] = Integer.parseInt(strArr[i]);
				 }
				 catch (NumberFormatException e) {
					intArr[i] = 0;
				}
				
			}return Arrays.stream(intArr);
		 };
		 
		 IntStream isr = list.stream().flatMapToInt(f);
//		 isr.forEach(s->System.out.println(s));
		 isr.forEach(System.out::println);
		 
		 
		 //숫자들의 갯수 합 평균 출력
		System.out.println("숫자의 갯수 "+list.stream().flatMapToInt(f).count());
		
		System.out.println("숫자의 합 "+list.stream().flatMapToInt(f).sum());
		
		System.out.println("숫자의 평균 "+list.stream()
		.flatMapToInt(f).average().getAsDouble());

	}
}

 

10

20

30

0

40

50

60

숫자의 갯수 7

숫자의 합 210

숫자의 평균 30.0


flatMap 예제2

package ex5_flatmap;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Student{
	String name;
	int score;
	public Student(String name, int score) {
		super();
		this.name = name;
		this.score = score;
	}
	@Override
	public String toString() {
		return "["+ name + ", score=" + score + "]";
	}
	
}
public class FlatMapEx3 {
	public static void main(String[] args) {
		List<Student> list1 = Arrays.asList(new Student("홍", 10),
				new Student("김", 5),
				new Student("LEE", 30),
				new Student("유", 60));
		List<Student> list2 = Arrays.asList(new Student("박", 14),
				new Student("choi", 30),
				new Student("하", 60));
		List<List<Student>> stu = new ArrayList<List<Student>>();
		stu.add(list1);
		stu.add(list2);//2개의 리스트 추가
		//stu.stream() : list를 요소로가진 스트림
		//.flatMap(s->s.stream()) : List<Student> -> Stream<Student>변경
		
//		stu.stream().flatMap(List::stream).forEach(System.out::println);
		stu.stream().flatMap(s->s.stream()).forEach(s->System.out.println(s));
				
	}
}

[홍, score=10]

[김, score=5]

[LEE, score=30]

[유, score=60]

[박, score=14]

[choi, score=30]

[하, score=60]

 


예제3 )

해당List의 요소를 " "간격으로 나눈 후

모두출력해봐라.

package ex5_flatmap;

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

public class Exam1 {

	public static void main(String[] args) {
		List<String> list = Arrays.asList("This is a Java book",
				"Lambda Expressions",
				"Java8 supports lambda Expressions");
		
		
		Function<String, Stream<String>> f = s->{
			return Arrays.stream(s.split(" "));
            //s.split(" ")으로 " "기준으로  문자를 나눠 String[]생성
			//String[] --> Stream<String>
		};
		
		
		list.stream().flatMap(f).forEach(s->System.out.println(s));
	}
}

This

is

a

Java

book

Lambda

Expressions

Java8

supports

lambda

Expressions

 


예제4)

Stream.of(..) :  ...내용으로 Stream 생성

package ex5_flatmap;

import java.util.Arrays;
import java.util.function.Function;
import java.util.stream.Stream;

public class Exam2 {
	public static void main(String[] args) {
		//Stream.of(..) -> 내용으로 Stream 생성
		Stream<String[]> stream = Stream.of(new String[] {"ABC","def","JKL"},
				new String[] {"abc","GHI","jkl"});
		
		Function<String[], Stream<String>> f = Arrays::stream;
//		f = s-> Arrays.stream(s);
		
		stream.flatMap(f).forEach(System.out::println);
		//Stream<String[]> --> Stream<String> 변경
	}

}

ABC

def

JKL

abc

GHI

jkl

 

 


1-3)  @@ Stream Sorted (스트림정렬) @@

 

package ex6_sort;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class SortedEx1 {

	public static void main(String[] args) {
		
		List<String> list = Arrays.asList("홍길동","김삿갓","이몽룡","임꺽정");
		list.stream().forEach(System.out::println);
		System.out.println();
		System.out.println("기본 정렬");
		list.stream().sorted().forEach(System.out::println);
		System.out.println();
		System.out.println("기본의 역순 정렬");
		list.stream().sorted(Comparator.reverseOrder())
		.forEach(System.out::println);
	}
}

홍길동

김삿갓

이몽룡

임꺽정

 

기본 정렬

김삿갓

이몽룡

임꺽정

홍길동

 

기본의 역순 정렬

홍길동

임꺽정

이몽룡

김삿갓

 

 


클래스를 활용한 Stream 정렬


* Student 클래스의 기본정렬 방식 구현 : 이름순 정렬


 * sorted() : Stream의 요소들을 정렬해 Stream 으로 리턴
 *       --> 요소들은 Comarable 객체로 형변환이 가능해야함(구현해야함)
 *       
 * sorted(Comparator) -> Comparator 객체가 구현된 형태로 정렬

 

Student 클래스

package student;

public class Student implements Comparable<Student>{
	String name;
	int ban;
	int eng;
	int math;
	int kor;
	public Student(String name, int ban, int eng, int math, int kor) {
		super();
		this.name = name;
		this.ban = ban;
		this.eng = eng;
		this.math = math;
		this.kor = kor;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getBan() {
		return ban;
	}

	public void setBan(int ban) {
		this.ban = ban;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}
	//총점 반환
	public int getTotal() {
		return eng+math+kor;
	}

	@Override
	public String toString() {
		return "[이름 : " + name + ", 반=" + ban + ", 영어=" + eng  
				+", 수학=" + math + ", 국어=" + kor + ", 총점 : "+(eng+math+kor)+"]";
	}

	@Override
	public int compareTo(Student o) {
		return name.compareTo(o.name);
	}
}

Student 클래스에서 Comparable을 구현 후  CompareTo메서드를 이름기준으로 오버라이딩!!!

----> Sorted() 시 이름기준으로 정렬됨!!!!

구동클래스

package ex6_sort;

import java.util.Arrays;
import java.util.List;

import student.Student;

public class SortedEx2 {
	public static void main(String[] args) {
		
		List<Student> list = Arrays.asList(new Student("홍길동", 1, 89, 56, 66),
				new Student("김삿갓", 1, 29, 46, 86),
				new Student("이몽룡", 1, 39, 86, 96),
				new Student("임꺽정", 1, 79, 66, 46),
				new Student("박아지", 1, 69, 36, 76));
		list.stream().sorted().forEach(System.out::println);
		//내가 만든 클래스에는 기본적으로 Comparable이 구현되어있지않음
		//구현 후 CompareTo메서드를 목적에맞게바꾸자
		System.out.println("총점순으로 정렬하기");
								//오름차순 정렬 : (s1,s2)->s1-s2 (결과가 음수면 s1이 앞이란 소리임)
								//내림차순 정렬 : (s1,s2) ->s2-s1 or (s1-s2)*-1
		list.stream().sorted((s1,s2)->(s1.getTotal()-s2.getTotal())*-1).forEach(System.out::println);
	}
}

[이름 : 김삿갓, 반=1, 영어=29, 수학=46, 국어=86, 총점 : 161]

[이름 : 박아지, 반=1, 영어=69, 수학=36, 국어=76, 총점 : 181]

[이름 : 이몽룡, 반=1, 영어=39, 수학=86, 국어=96, 총점 : 221]

[이름 : 임꺽정, 반=1, 영어=79, 수학=66, 국어=46, 총점 : 191]

[이름 : 홍길동, 반=1, 영어=89, 수학=56, 국어=66, 총점 : 211]

총점순으로 정렬하기

[이름 : 이몽룡, 반=1, 영어=39, 수학=86, 국어=96, 총점 : 221]

[이름 : 홍길동, 반=1, 영어=89, 수학=56, 국어=66, 총점 : 211]

[이름 : 임꺽정, 반=1, 영어=79, 수학=66, 국어=46, 총점 : 191]

[이름 : 박아지, 반=1, 영어=69, 수학=36, 국어=76, 총점 : 181]

[이름 : 김삿갓, 반=1, 영어=29, 수학=46, 국어=86, 총점 : 161]

 

 


Sorted 예제1)

 

package ex6_sort;

import java.util.Comparator;
import java.util.stream.Stream;

import student.Student;

public class SortedEx3 {
	public static void main(String[] args) {
		Stream<Student> stStream = Stream.of(new Student("김길동", 1, 89, 50, 78),
				new Student("박아지", 1, 60, 10, 70),
				new Student("김삿갓", 1, 79, 20, 55),
				new Student("임마", 3, 49, 30, 50),
				new Student("이몽룡", 2, 50, 40, 60),
				new Student("유관순", 4, 89, 80, 88));
		stStream.sorted(
				Comparator.comparing(Student::getBan)//반별정렬(1차정렬) 메서드참조방식
				.thenComparing(Comparator.naturalOrder()))//기본정렬(2차정렬)
		.forEach(System.out::println);
	}
}

[이름 : 김길동, 반=1, 영어=89, 수학=50, 국어=78, 총점 : 217]

[이름 : 김삿갓, 반=1, 영어=79, 수학=20, 국어=55, 총점 : 154]

[이름 : 박아지, 반=1, 영어=60, 수학=10, 국어=70, 총점 : 140]

[이름 : 이몽룡, 반=2, 영어=50, 수학=40, 국어=60, 총점 : 150]

[이름 : 임마, 반=3, 영어=49, 수학=30, 국어=50, 총점 : 129]

[이름 : 유관순, 반=4, 영어=89, 수학=80, 국어=88, 총점 : 257]

 

 


반 별로 정렬 후

총점순 ,총점의 역순,영어점수 순 등 다양한 정렬방식 써보자

 

(Stream은 한번순회하면 사라지는 1회용이란 것을 잊지말자

List<Student>만든 후 출력할떄마다 stream을 간편하게 만들자!! )

 

package ex6_sort;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import student.Student;

public class Exam1 {
	public static void main(String[] args) {
	//Stream은 순회 후 초기화되므로 List를 미리 만들어 재사용성을 높임
		List<Student> list = Arrays.asList(new Student("김길동", 1, 89, 50, 78),
				new Student("박아지", 1, 60, 10, 70),
				new Student("김삿갓", 1, 79, 20, 55),
				new Student("임마", 3, 49, 30, 50),
				new Student("이몽룡", 2, 50, 40, 60),
				new Student("이지상", 2, 30, 30, 30),
				new Student("유관순", 4, 89, 80, 88));
		
		System.out.println("==반별로 정렬 후 총점의 오름차순정렬!!==");
		//list ---> Stream(Student) 생성
		list.stream().sorted(Comparator.comparing(Student::getBan)//메서드정렬
				.thenComparing((s1,s2)->s1.getTotal()-s2.getTotal())
				//thenComparing 은 람다식으로 정렬이가능함
				
//				.thenComparing(s->s.getTotal())
//				.thenComparing(Comparator.comparing(Student::getTotal))
				)
		.forEach(System.out::println);

//---------------------------==반별로 정렬 후 총점의 내림차순정렬==---------------------------------------------------
		System.out.println("==반별로 정렬 후 총점의 내림차순정렬!!==");
		
		list.stream().sorted(Comparator.comparing(Student::getBan)
				.thenComparing((s1,s2)->(s1.getTotal()-s2.getTotal())*-1)
//				.thenComparing(s->s.getTotal()*-1)
				)
		.forEach(System.out::println);
//----------------------------반 별 영어점수 내림차순--------------------------------------------------		
		System.out.println("==반 별 영어점수의 내림정렬 ==");
		//반별 영어점수의 내림 정렬하기
		list.stream().sorted(Comparator.comparing(Student::getBan)
				.thenComparing(s->s.getEng()*-1)
				)
		.forEach(System.out::println);
//-----------------------------반 별 수학점수 오름차순--------------------------------------------------
		System.out.println("=== 반 별 수학점수의 오름차순정렬 === ");
		list.stream().sorted(Comparator.comparing(Student::getBan)
				.thenComparing(s->s.getMath())
				)
		.forEach(System.out::println);
	}
}

==반별로 정렬 후 총점의 오름차순정렬!!==

[이름 : 박아지, 반=1, 영어=60, 수학=10, 국어=70, 총점 : 140]

[이름 : 김삿갓, 반=1, 영어=79, 수학=20, 국어=55, 총점 : 154]

[이름 : 김길동, 반=1, 영어=89, 수학=50, 국어=78, 총점 : 217]

[이름 : 이지상, 반=2, 영어=30, 수학=30, 국어=30, 총점 : 90]

[이름 : 이몽룡, 반=2, 영어=50, 수학=40, 국어=60, 총점 : 150]

[이름 : 임마, 반=3, 영어=49, 수학=30, 국어=50, 총점 : 129]

[이름 : 유관순, 반=4, 영어=89, 수학=80, 국어=88, 총점 : 257]

 

==반별로 정렬 후 총점의 내림차순정렬!!==

[이름 : 김길동, 반=1, 영어=89, 수학=50, 국어=78, 총점 : 217]

[이름 : 김삿갓, 반=1, 영어=79, 수학=20, 국어=55, 총점 : 154]

[이름 : 박아지, 반=1, 영어=60, 수학=10, 국어=70, 총점 : 140]

[이름 : 이몽룡, 반=2, 영어=50, 수학=40, 국어=60, 총점 : 150]

[이름 : 이지상, 반=2, 영어=30, 수학=30, 국어=30, 총점 : 90]

[이름 : 임마, 반=3, 영어=49, 수학=30, 국어=50, 총점 : 129]

[이름 : 유관순, 반=4, 영어=89, 수학=80, 국어=88, 총점 : 257]

 

==반 별 영어점수의 내림정렬 ==

[이름 : 김길동, 반=1, 영어=89, 수학=50, 국어=78, 총점 : 217]

[이름 : 김삿갓, 반=1, 영어=79, 수학=20, 국어=55, 총점 : 154]

[이름 : 박아지, 반=1, 영어=60, 수학=10, 국어=70, 총점 : 140]

[이름 : 이몽룡, 반=2, 영어=50, 수학=40, 국어=60, 총점 : 150]

[이름 : 이지상, 반=2, 영어=30, 수학=30, 국어=30, 총점 : 90]

[이름 : 임마, 반=3, 영어=49, 수학=30, 국어=50, 총점 : 129]

[이름 : 유관순, 반=4, 영어=89, 수학=80, 국어=88, 총점 : 257]

 

=== 반 별 수학점수의 오름차순정렬 ===

[이름 : 박아지, 반=1, 영어=60, 수학=10, 국어=70, 총점 : 140]

[이름 : 김삿갓, 반=1, 영어=79, 수학=20, 국어=55, 총점 : 154]

[이름 : 김길동, 반=1, 영어=89, 수학=50, 국어=78, 총점 : 217]

[이름 : 이지상, 반=2, 영어=30, 수학=30, 국어=30, 총점 : 90]

[이름 : 이몽룡, 반=2, 영어=50, 수학=40, 국어=60, 총점 : 150]

[이름 : 임마, 반=3, 영어=49, 수학=30, 국어=50, 총점 : 129]

[이름 : 유관순, 반=4, 영어=89, 수학=80, 국어=88, 총점 : 257]

 

 


1- 4) Peek , ForEach 함수 

peek : 중간 처리 반복자
 *   중간단계에서 추가 작업시 사용 됨
 *  다음단계 처리가 없다면 동작 실행X
   
 
 * forEach : 최종 단계 반복자 ( 다음 단계가없음)

package ex7_peek;

import java.util.Arrays;

public class PeekvsForEachEx1 {
public static void main(String[] args) {
	int[] intArr = {1,2,3,4,5};
	System.out.println("peek 메서드 연습");
	//peek : 짝수의 합 출력 , 중간단계에서 작업 수행
	int tot=
			Arrays.stream(intArr).filter(a->a%2==0)//짝수만넘겨
			.peek(n->System.out.print(n+"+")).sum();
			//sum()이없다면 peek동작 실행X
	
	
	System.out.println("=="+tot);
	
	System.out.println("ForEach 메서드 연습");
	Arrays.stream(intArr).filter(a->a%2==0)//짝수만 넘긴다.
	.forEach(n->System.out.println(n+","));
}
}

peek 메서드 연습

2+4+==6

ForEach 메서드 연습

2,

4,

 

 


peek forEach 예제

1부터100까지의 랜덤한 수 10개를 뽑아 홀수만 더해보자

package ex7_peek;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
import java.util.stream.IntStream;

public class Exam1 {
	public static void main(String[] args) {
		
		System.out.println("1부터100까지의 랜덤한수 10개를 뽑아 홀수만 더해보자");
		System.out.println("== 리스트 이용 ==");
		ArrayList<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < 9; i++) {
			int num = new Random().nextInt(100)+1;
			list.add(num);
		}
		System.out.println("리스트 : "+list);
		
		int sum = list.stream().mapToInt(s->s.intValue()).filter(s->s%2==1)
				.peek(s->System.out.print(s+",")).sum();
		//maptoInt(s->s.intValue) : Stream<Integer> 
		//-> s.value() 로 int형을 반환해 IntStream 으로변경

		
		System.out.println(" = "+sum);
//------------------------------------배열을 사용한 방법-----------------------
		System.out.println("== 배열을 이용 ==");
		int arr[] = new int[10];
		for (int i = 0; i < arr.length; i++) {
			arr[i]= new Random().nextInt(100)+1;
		}
		int sum2 = Arrays.stream(arr).filter(s->s%2==1)
		.peek(s->System.out.print(s+",")).sum();
		
		System.out.println(" = "+sum2);
		
//----------------------------------------Random클래스------------------------
		System.out.println("== Random클래스 이용 ==");
		IntStream isr = new Random().ints(10,1,100);
		//ints(난수의 갯수, 시작숫자 , 종료 숫자) : 
		int tot = isr.filter(a->a%2==1)
		.peek(i->System.out.print(i+",")).sum();
		System.out.println("홀수의합 : "+tot);
	}
}

Random . ints(난수의갯수 , 시작숫자 , 종료숫자 ) 로 더욱간편하게 구할수있음 : 

 


1-5) Sequencial  ,  Parallel

  (순차   , 병렬 )

 

package ex8_parallel;

import java.util.Arrays;
import java.util.List;

public class SequencialVsParallelEx2 {
	public static void main(String[] args) {
		List<Integer> list = Arrays.asList(0,1,2,3,4,5,6,7,8,9);
		System.out.println("@@ Stream @@");
		long start = System.nanoTime();//1970년부터 현재까지 시간을 나노초리턴
		list.stream().forEach(a->System.out.println(Thread.currentThread()+":"+a));
		long end = System.nanoTime();
		double pow = Math.pow(10, -9);
		System.out.printf("순차 처리 시간 %,d ",(end-start));
		System.out.println();
		
		//병렬처리
		System.out.println("\n@@ parallelStream @@");
		start = System.nanoTime();
		list.parallelStream().forEach(a->System.out.println(Thread.currentThread()+":"+a));
		end = System.nanoTime();
		System.out.printf("병렬 처리 시간 : %,d ",(end-start));
	}
}

@@ Stream @@

Thread[#1,main,5,main]:0

Thread[#1,main,5,main]:1

Thread[#1,main,5,main]:2

Thread[#1,main,5,main]:3

Thread[#1,main,5,main]:4

Thread[#1,main,5,main]:5

Thread[#1,main,5,main]:6

Thread[#1,main,5,main]:7

Thread[#1,main,5,main]:8

Thread[#1,main,5,main]:9

순차 처리 시간 19,335,900

 

@@ parallelStream @@

Thread[#1,main,5,main]:6

Thread[#1,main,5,main]:5

Thread[#24,ForkJoinPool.commonPool-worker-4,5,main]:0

Thread[#25,ForkJoinPool.commonPool-worker-5,5,main]:3

Thread[#23,ForkJoinPool.commonPool-worker-3,5,main]:1

Thread[#25,ForkJoinPool.commonPool-worker-5,5,main]:9

Thread[#21,ForkJoinPool.commonPool-worker-1,5,main]:2

Thread[#1,main,5,main]:4

Thread[#22,ForkJoinPool.commonPool-worker-2,5,main]:8

Thread[#24,ForkJoinPool.commonPool-worker-4,5,main]:7

병렬 처리 시간 : 4,100,400


1-6) Consumer AndThen


 * Consumer : void accept(T) , 매개변수T 리턴타입 X
 *   default 메서드 andThen()메서드
 * andThen() 메서드 : 순차적으로 연결해서 실행해주는 메서드
 * 
 * default 메서드 : 인터페이스의 멤버 구현부존재.(인스턴스메서드)

package ex8_compose;

import java.util.function.Consumer;

import clazz.Member;

public class ConsumerAndThenEx1 {
	public static void main(String[] args) {
		Consumer<Member> consumerA = m->{
			System.out.println("consumberA : "+m.getName());
			//입력받은 m의 getName()을 호출해라 (m은 Member인스턴스 여야만 함)
		};
		consumerA.accept(new Member("홍길동", "hkd", null));//m의 값 만들기
		
		
		Consumer<Member> consumerB = m->{
			System.out.println("consumberB : "+m.getId());
			//입력받은 m의 getId()을 호출해라 (m은 Member 인스턴스여야만 함)
		};
		consumerB.accept(new Member("홍길동", "hkd", null));//m의 값 만들기
		
		Consumer<Member> consumerC = m->{
			System.out.println("consumberC : "+m.getAddress());
			
		};
		consumerC.accept(new Member("홍길동", "hkd", null));//m의 값 만들기
		
		System.out.println("===================================");
		
		Consumer<Member> consumerAB = consumerA
				.andThen(consumerB)
				.andThen(consumerC)//andThen으로 계속 연결
				.andThen(consumerB)
				.andThen(consumerC);
		consumerAB.accept(new Member("홍길동", "hkd", null));
	}

}

consumberA : 홍길동

consumberB : hkd

consumberC : null

===================================

consumberA : 홍길동

consumberB : hkd

consumberC : null

consumberB : hkd

consumberC : null

 


1-7) Function   andThen()  , compose()

 


 * Function<T,R> : R apply(T) : 매개변수 T ,리턴타입 R
 * --두개의 인터페이스 객체연결
 * andThen() : 디폴트메서드 , 순차적 연결 실행 functionA리턴값을 functionB 매개변수로전달

 * compose() :  디폴트메서드 , 매개변수부터 실행(역순) 
 *  functionA리턴값을 functionB 매개변수로전달

package ex8_compose;

import java.util.function.Function;

import clazz.Address;
import clazz.Member;

public class FuctionAndThenComposeEx1 {
	public static void main(String[] args) {
		Function<Member, Address> functionA;// Address apply(Member)
		Function<Address, String> functionB;// String apply(Address)
		Function<Member, String> functionAB;// String apply(Member)
		String city;
		functionA = m-> m.getAddress();//Member을 넣어 Address 반환
		functionB = m-> m.getCity();//String을 넣어 Address반환
		functionAB = functionA.andThen(functionB);
		//functionA -> functionB -> functionAB 순으로실행
		//Address functionA.apply(Member)
		//String  funcionB.apply(Address) 
		//funcionB의 반환값 String을 FunctionAB에 넣음
		city = functionAB.apply(
				new Member("홍길동", "hong", new Address("한국", "서울")) );
		System.out.println("compse--> 거주도시 : "+city);
		
		
		System.out.println();
		
		
		Address address = new Address("한국", "서울");
		functionAB = functionB.compose(functionA);
		//compose는 리턴값이 있어야하므로 Consumer(리턴값X)에는 사용X
		//functionAB <--- functionB<----- funtionA 실행
		city = functionAB.apply(
				new Member("홍길동", "hong", address) );
		System.out.println("compse--> 거주도시 : "+city);
	}
}

실행결과는 같음

andThen() : 순차

compose() : 역순

compse--> 거주도시 : 서울

 

compse--> 거주도시 : 서울