부트캠프(Java)

자바/스프링 부트캠프 21일차

동곤일상 2025. 2. 28. 15:03
반응형

1)Stream - Collect

1-1)Boxed

1-2) collect

1-3) Reducing

1-4)Reducing

1-5) Group

collect의 다양한 함수

 

 


 

1) @ @  Stream . Collect @@

 

 1-1 ) Boxed


 * Box : 기본자료형==> 객체화
 * asDoubleStream() : IntStream => DoubleStream
 * boxed() : IntStream -> Stream<Integer>

package ex10_collect;

import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class Ex01_Boxed {
	static int sum = 0;
	public static void main(String[] args) {
		int[] intArray = {1,2,3,4,5};
		IntStream intStream = Arrays.stream(intArray);
		//IntStream :요소의 자료형이 int형인 Stream
		//DoubleStream :요소의 자료형이 double형인 Stream
		//asLongStream() : IntStream==> LongStream
		intStream.asDoubleStream().forEach(s->System.out.print(s+", "));
		System.out.println();
		/*
		 * boxed() : Wrapper 클래스로 변경
		 */
		intStream = Arrays.stream(intArray);
		Stream<Integer> is = intStream.boxed();
		//obj.getClass()
		is.forEach(obj->System.out.print(obj.getClass()+", "));
		System.out.println();
		Arrays.stream(intArray).boxed().forEach(i->System.out.print(i.intValue()+","));
	}

}

1.0, 2.0, 3.0, 4.0, 5.0,

class java.lang.Integer, class java.lang.Integer, class java.lang.Integer, class java.lang.Integer, class java.lang.Integer,

1,2,3,4,5,

 

 


1-2 ) Collect 


 * collect(Collector 인터페이스 ) : Stream을 Collection객체로 변경


 * Collectors 클래스 : Collector 인터페이스 구현체
*  toList() : List객체로변경
 *  toMap(key,value) : Map객체로  변경

    counting() : 요소의갯수를 Long타입으로 반환

 

 

  toArray(요소의자료형[]::new) : Stream을 배열로 변경

package ex10_collect;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import clazz.Student;

public class Ex02_Collect {
	public static void main(String[] args) {
		Student[] stuArr = {   new Student("이자바", 3, 30, 66, 78),
			new Student("김자바", 1, 50, 70, 68),
			new Student("안자바", 2, 60, 80, 42),
			new Student("박자바", 2, 80, 20, 30),
			new Student("소자바", 1, 70, 30, 67),
			new Student("나자바", 3, 90, 40, 58),
			new Student("감자바", 1, 20, 45, 55)};
		System.out.println("1. 학생이름만 뽑아서 List<String>에 저장");
		//Stream<Student> Stream.of(stuArr)
		//Stream<String> map(Student::getName) //getName은 Student의 name Getter
		//collect(Collectors.toList()) : Stream(String) --> List<String>
		List<String> names = Stream.of(stuArr)
				.map(s->s.getName()) //Stream<Student> --> Stream<String> 으로바꿔줌
				.collect(Collectors.toList());
//		List<String> names = Stream.of(stuArr).map(Student::getName).collect(Collectors.toList());
		
		System.out.println(names);
		System.out.println("학생 이름만 뽑아서 String[] 에 저장");
		String[] nameArr = Stream.of(stuArr)
				.map(Student::getName)
				.toArray(String[]::new);//Strema<String>-->새로운String[] 객체로 생성
		
		System.out.println(Arrays.asList(nameArr));
		
		System.out.println("3. Map<String , Student>로 변환 key는 name");
		Map<String,Student> map = Stream.of(stuArr)
				/*
				 * toMap(Function<? super Student ,? extends String> KeyMapper
				 * 							: Student객체를 매개변수입력 String리턴
				 * 
				 * 		(Function<? super Student , ? extends Studnet> valueMapper
				 * 								: Student객체를 매개변수입력. Student리턴
				 */
				.collect(Collectors.toMap(s->s.getName(), s->s));
		    //s : Student자료형
			//key : s.getName()
			//value : s->s( 자기 자신의 자료형을 나타냄)
		for (String s : map.keySet()) {
			System.out.println(s+" : "+map.get(s));
		}
		
		System.out.println("4 . Stream의 요소의 갯수 출력하기");
		long count = Stream.of(stuArr).count();
		System.out.println("요소의갯수 : "+count);
       Long cCount = Stream.of(stuArr).collect(Collectors.counting());
		System.out.println("요소의갯수(collect이용) "+cCount);
		}
	}

1. 학생이름만 뽑아서 List<String>에 저장

[이자바, 김자바, 안자바, 박자바, 소자바, 나자바, 감자바]

학생 이름만 뽑아서 String[] 에 저장

[이자바, 김자바, 안자바, 박자바, 소자바, 나자바, 감자바]

3. Map<String , Student>로 변환 key는 name

안자바 : [이름 : 안자바, 반=2, 영어=60, 수학=80, 국어=42, 총점 : 182]

김자바 : [이름 : 김자바, 반=1, 영어=50, 수학=70, 국어=68, 총점 : 188]

박자바 : [이름 : 박자바, 반=2, 영어=80, 수학=20, 국어=30, 총점 : 130]

나자바 : [이름 : 나자바, 반=3, 영어=90, 수학=40, 국어=58, 총점 : 188]

감자바 : [이름 : 감자바, 반=1, 영어=20, 수학=45, 국어=55, 총점 : 120]

이자바 : [이름 : 이자바, 반=3, 영어=30, 수학=66, 국어=78, 총점 : 174]

소자바 : [이름 : 소자바, 반=1, 영어=70, 수학=30, 국어=67, 총점 : 167]

4 . Stream의 요소의 갯수 출력하기

요소의갯수 : 7

요소의갯수(collect이용) 7

 


1-3 ) Reducing


 * Collectors.reducing(10000,Student::getEng,Integer::sum)
 * 10000 : 초기값
 * Student::getEng : 선택 컬럼
 * Integer::Sum : 함수

package ex10_collect;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import clazz.Student;

public class Ex03_collect {
	public static void main(String[] args) {
		Student[] stuArr = {   
				new Student("이자바", 3, 30, 66, 78),
				new Student("김자바", 1, 50, 70, 68),
//				new Student(name, ban,eng,math,kor)
				new Student("안자바", 2, 60, 80, 42),
				new Student("박자바", 2, 80, 20, 30),
				new Student("소자바", 1, 70, 30, 67),
				new Student("나자바", 3, 90, 40, 58),
				new Student("감자바", 1, 20, 45, 55)};
		System.out.println("1, eng점수의 합 Collectors.reducing");
		
        
		Integer engTotal = Stream.of(stuArr).collect(Collectors.reducing(10000,Student::getEng,Integer::sum));
		System.out.println("형어접수의 합 : "+engTotal);
		
		List<Integer> number = Arrays.asList(1,2,3,4,5);
		Optional<Integer> sum = number.stream().collect(Collectors.reducing((a,b)->a+b));
		sum.ifPresent(System.out::println);
		//Optional : 값이 없을 가능성이있음.
		//ifPresent : 값이 있으면 값으로 지정된 작업 수행, 그렇지 않으면 아무 작업도 수행하지 않습니다.
		
		 number = Arrays.asList();
		Optional<Integer> sum2 = number.stream().collect(Collectors.reducing((a,b)->a+b));
		sum2.ifPresent(System.out::println);//값이없는데 출력시도 --> 아무일도 일어나지않음
	}
}

1, eng점수의 합 Collectors.reducing

형어접수의 합 : 10400

15

 


1-4 )collect의 다양한 함수

maxBy , MinBy ,joining , Colletors.toCollection(()->new HashSet())

 

Student2클래스

Enum은 지정된값만 사용할수있음 다른걸 시도하면 오류!!

package clazz;

public class Student2 {
	public enum Gender {MALE,FEMALE};
	public enum City {SEOUL,BUSAN};
	//enum : 열거형 ( 범위내의 값만 사용가능)
	String name;
	int score;
	private Gender gender;
	private City city;
	
	public Student2(String name, int score, Gender gender, City city) {
		this.name = name;
		this.score = score;
		this.gender = gender;
		this.city = city;
	}
	
	public Student2(String name , int score , Gender gender) {
		this(name,score,gender,null); //위에 생성자로올라감
	}

	public String getName() {
		return name;
	}

	public int getScore() {
		return score;
	}

	public Gender getGender() {
		return gender;
	}

	public City getCity() {
		return city;
	}

	@Override
	public String toString() {
		return  name + ", score=" + score + ", gender=" + gender + ", city=" + city ;
	}
	
	


}

 

구동클래스

package ex10_collect;

import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import clazz.Student2;
import clazz.Student2.City;
import clazz.Student2.Gender;

public class Ex04_Collect {
	public static void main(String[] args) {
		List<Student2> list = Arrays.asList(
				new Student2("홍길동", 50,Gender.MALE),
				new Student2("유관순", 90,Gender.FEMALE,City.SEOUL),
				new Student2("박아지", 30,Gender.MALE,City.BUSAN),
				new Student2("이시안", 80,Gender.FEMALE,City.SEOUL));
		
		System.out.println("1. 남학생의 이름 , 점수 출력해보기(list로)");
		List<Student2> maleList= 
				list.stream() // Stream(Student2)반환
				.filter(s->s.getGender().equals(Gender.MALE)) //s(Student2)의 성이 Gender.MALE과 같다면 넘긴다.
				.collect(Collectors.toList()); //Stream -> List로 변환
		
		maleList.stream().forEach(s->System.out.println(s.getName()+", "+s.getScore()));
		
		System.out.println("2.List로 생성해 여학생의 이름,점수 출력");
		List<Student2> femaleList= 
				list.stream() // Stream(Student2)반환
				.filter(s->s.getGender().equals(Gender.FEMALE)) //s(Student2)의 성이 Gender.FEMALE과 같다면 넘긴다.
				.collect(Collectors.toList()); //Stream -> List로 변환
		
		femaleList.stream().forEach(s->System.out.println(s.getName()+", "+s.getScore()));
		
		System.out.println("3.Set으로 생성해 여학생의 이름 점수 출력");
				Set<Student2> femaleSet = list.stream() // Stream(Student2)반환
				.filter(s->s.getGender().equals(Gender.FEMALE)) //s(Student2)의 성이 Gender.FEMALE과 같다면 넘긴다.
				.collect(Collectors.toCollection(HashSet<Student2>::new));
//				.collect(Collectors.toCollection(()->new HashSet<Student2>()));
				//.coleect(Collectors.toSet());
				
				femaleSet.stream().forEach(s->System.out.println(s.getName()+", "+s.getScore()));
				
//--------------------------------------최대값 , 최소값---------------------------------------------------------
		System.out.println("4. Score최대값은 누구인가?  ");
		Optional<Student2> max = 
				 list.stream()
				.collect(Collectors.maxBy(Comparator.comparing(s->s.getScore())));
		max.ifPresent(System.out::println);
		System.out.println("점수가 가장높은학생 : "+max.get().getName()+" score : "+max.get().getScore());
		
		System.out.println("5.Score 최소값은 누구인가??");
		Optional<Student2> min = list.stream()
		.collect(Collectors.minBy(Comparator.comparing(s->s.getScore())));
		min.ifPresent(s->System.out.println(s));
		System.out.println("점수가 가장낮은학생 : "+min.get().getName()+" score : "+min.get().getScore());
		
//---------------------------------------------joining-----------------------------------------------------
		System.out.println("6.list 학생의 이름들을 출력하기");
		list.stream().map(s->s.getName()).forEach(s->System.out.print(s+", "));
		System.out.println();
//		list.stream().map(Student2::getName).forEach(s->System.out.print(s+", "));
		String names = list.stream().map(Student2::getName)
		.collect(Collectors.joining("-" , "[" , "]"));
		System.out.println(names);
	}
}


 * Collectors.joining(구문자 , 시작문자 , 끝문자);
 * Stream의요소를 연결해 문자열 리턴
 * 구문자 : 문자열 사이의 구분 표시

1. 남학생의 이름 , 점수 출력해보기(list로)

홍길동, 50

박아지, 30

 

2.List로 생성해 여학생의 이름,점수 출력

유관순, 90

이시안, 80

 

3.Set으로 생성해 여학생의 이름 점수 출력

이시안, 80

유관순, 90

 

4. Score최대값은 누구인가?

유관순, score=90, gender=FEMALE, city=SEOUL

점수가 가장높은학생 : 유관순 score : 90

 

5.Score 최소값은 누구인가??

박아지, score=30, gender=MALE, city=BUSAN

점수가 가장낮은학생 : 박아지 score : 30

 

6.list 학생의 이름들을 출력하기

홍길동, 유관순, 박아지, 이시안,

[홍길동-유관순-박아지-이시안]

 


1-5 ) Group

groupingBy(그룹기준컬럼 , 값 ) 

package ex11_group;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import clazz.Student2;
import clazz.Student2.City;
import clazz.Student2.Gender;

public class Ex02_group {
	public static void main(String[] args) {
		List<Student2> list = Arrays.asList(
				new Student2("홍길동", 51,Gender.MALE,City.BUSAN),
				new Student2("유관순", 93,Gender.FEMALE,City.SEOUL),
				new Student2("박아지", 32,Gender.MALE,City.BUSAN),
				new Student2("이시안", 83,Gender.FEMALE,City.SEOUL));
		
		//성별로 평균점수 구하기
	
				Double avgM = list.stream()
				.filter(s->s.getGender()==Gender.MALE)
				.mapToInt(s->s.getScore()).average().getAsDouble();
				
				System.out.println("남자의평균 : "+avgM);
				
				Double avgF = list.stream()
						.filter(s->s.getGender()==Gender.FEMALE)
						.collect(Collectors.averagingDouble(Student2::getScore));
				
				System.out.println("여자평균점수 : "+avgF);
				
		
				
				//averaginDouble(Student2::getScore) : Student2의getScore의 평균을 Double반환
				Map<Gender, Double> map1 = list.stream()
				.collect(Collectors.groupingBy(
						Student2::getGender,Collectors.averagingDouble(s->s.getScore())/*==(Student2::getScore)*/
						));
				System.out.println(map1);
				//key값이 Gender value가 평균인 map객체 출력
				
				
//-----------------------------------도시별로 이름 출력-----------------------------
				
				System.out.print("서울지역 : ");
				list.stream().filter(s->s.getCity()==City.SEOUL).forEach(s->System.out.print(s.getName()+" "));
				System.out.println();
				
				System.out.print("부산지역 : ");
				list.stream().filter(s->s.getCity()==City.BUSAN).forEach(s->System.out.print(s.getName()+" "));
				System.out.println();
				
				Map<City, String> map2 = list.stream()
						.collect(Collectors.groupingBy(Student2::getCity,//도시가 Key
						Collectors.mapping(Student2::getName,Collectors.joining("," , "[" , "]")) ) );
		//각 도시에 매핑되는 Student2의 getName을   , 로 나눔.
		//mapping : Student2::getName 데이터들을 변환하기위한함수 --> 데이터선택
		//Collectors.joinning("," , "[" , "]") -> 선택된데이터를 다음과같이 처리
				System.out.println(map2);
	}
}

남자의평균 : 41.5

여자평균점수 : 88.0

{MALE=41.5, FEMALE=88.0}

서울지역 : 유관순 이시안

부산지역 : 홍길동 박아지

{SEOUL=[유관순,이시안], BUSAN=[홍길동,박아지]}

 

 


다음과같은 txt를 읽어서 

월별로 판매수량을 나타내보자

new Car(int month, int con, String name, int qty, String remark)

형식의 클래스를 만들어서 map으로 해당객체 반환 후group으로 month를 key로 qty를 value로 설정해보자

 

.collect(Collectors.groupingBy(Car::getMonth,// key 값
Collectors.summingLong(Car::getQty))); //Qty 의 합

package ex11_group;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
import java.util.stream.Collectors;
import clazz.Car;

public class Ex01_Product {
	public static void main(String[] args) throws FileNotFoundException  {
		BufferedReader br = new  BufferedReader(new FileReader("product.txt"));

		//BufferReader : 파일을 한줄씩 읽을 수 있음 

		//월별 판매현황을 map객체로
		Map<Integer, Long> map = br.lines()
				.map(s->{ // Stream<String> => Stream<car>
					//s : String. product.txt 파일의 한줄
					String[] str = s.split(",");
					String temp ="";
					try {
						temp=str[4]; // 상태3(반품)인 경우 반품 사유
					}catch(ArrayIndexOutOfBoundsException e) {
						temp="";
					}
//					new Car(int month, int con, String name, int qty, String remark)
					return new Car(Integer.parseInt(str[0]) // 월
							,Integer.parseInt(str[1]),// 상태 1: 생산 2: 판매 3: 반품
							str[2], 					// 자동차명
							Integer.parseInt(str[3]),// 수량
							temp); 				//  반품사유
				}) // 결과 Stream<Car>
				.filter(s->s.getCon()==2) // con멤버 값이 2 == 판매
				.collect(Collectors.groupingBy(Car::getMonth,// key 값
						Collectors.summingLong(Car::getQty))); //Qty 의 합
		System.out.println(map);
	
		map.entrySet().stream().map(s->{
			//s.getKey()는 Integer 타입임 +""을 붙여 String 타입 반환
			String temp = s.getKey()+"";
			if(s.getKey() <10) temp ="0"+temp; //10월보다 작은 월은 key앞에0을 붙여줌
			return (temp+"월 판매 수량 :"+s.getValue());
		}).sorted().forEach(s->System.out.println(s));
	}
}

{1=4, 2=10, 4=9, 5=9, 6=1, 7=15, 8=1, 9=4, 10=5, 11=20, 12=12}

01월 판매 수량 :4

02월 판매 수량 :10

04월 판매 수량 :9

05월 판매 수량 :9

06월 판매 수량 :1

07월 판매 수량 :15

08월 판매 수량 :1

09월 판매 수량 :4

10월 판매 수량 :5

11월 판매 수량 :20

12월 판매 수량 :12