JAVA4_13_그룹화와 분할

charl hi·2021년 10월 13일
0

JAVA4

목록 보기
13/13

링크텍스트

Collectors 클래스 2

스트림의 그룹화와 분할

partitioningBy()

Collector partitioningBy(Predicate predicate)
Collector partitioningBy(Predicate predicate, Collector downstream)
  • 스트림을 2분할 한다.

예)



ex14_10

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.function.*;
import static java.util.stream.Collectors.*;
import static java.util.Comparator.*;

class Student2{
	String name;
	boolean isMale;
	int hak;
	int ban;
	int score;
	
	Student2(String name, boolean isMale, int hak, int ban, int score){
		this.name = name;
		this.isMale = isMale;
		this.hak = hak;
		this.ban = ban;
		this.score = score;
	}

	public String getName() {return name;}
	public boolean isMale() {return isMale;	}
	public int getHak() {return hak;}
	public int getBan() {return ban;}
	public int getScore() {return score;}

	@Override
	public String toString() {
		return String.format("[%s, %s, %d학년 %d반, %3d점]",
				name, isMale? "남" : "여", hak, ban, score);
	}
	
	//***groupingBy()에서 사용
	enum Level{	HIGH, MID, LOW}	//성적을 상, 중, 하 세 단계로 분류
	
	
}


public class Ex14_10 {

	public static void main(String[] args) {
		Student2[] stuArr = {
				new Student2("나자바", true,  1, 1, 300),	
				new Student2("김지미", false, 1, 1, 250),	
				new Student2("김자바", true,  1, 1, 200),	
				new Student2("이지미", false, 1, 2, 150),	
				new Student2("남자바", true,  1, 2, 100),	
				new Student2("안지미", false, 1, 2,  50),	
				new Student2("황지미", false, 1, 3, 100),	
				new Student2("강지미", false, 1, 3, 150),	
				new Student2("이자바", true,  1, 3, 200),	
				new Student2("나자바", true,  2, 1, 300),	
				new Student2("김지미", false, 2, 1, 250),	
				new Student2("김자바", true,  2, 1, 200),	
				new Student2("이지미", false, 2, 2, 150),	
				new Student2("남자바", true,  2, 2, 100),	
				new Student2("안지미", false, 2, 2,  50),	
				new Student2("황지미", false, 2, 3, 100),	
				new Student2("강지미", false, 2, 3, 150),	
				new Student2("이자바", true,  2, 3, 200)	
		};
		
		System.out.println("1. 단순분할(성별로 분할)");
		Map<Boolean, List<Student2>> stuBySex = Stream.of(stuArr).
				collect(partitioningBy(Student2::isMale));
		//b -> b.isMale()
		List<Student2> maleStudent = stuBySex.get(true);
		List<Student2> femaleStudent = stuBySex.get(false);
		
		for(Student2 s : maleStudent)
			System.out.println(s);
		for(Student2 s : femaleStudent)
			System.out.println(s);
		
		System.out.printf("%n2. 단순분할 + 통계(성별 학생 수)%n");
		Map<Boolean, Long> stuNumBySex = Stream.of(stuArr).
				collect(partitioningBy(Student2::isMale, counting()));
		
		System.out.println("남학생 수: "+stuNumBySex.get(true));
		System.out.println("여학생 수: "+stuNumBySex.get(false));

		System.out.printf("%n3. 단순불할 + 통계(성별 1등)%n");
		Map<Boolean, Optional<Student2>> topScoreBySex = Stream.of(stuArr).
				collect(partitioningBy(Student2::isMale,
								maxBy(comparingInt(Student2::getScore))
				));
		
		System.out.println("남학생 1등: "+topScoreBySex.get(true));
		System.out.println("여학생 1등: "+topScoreBySex.get(false));
		
		Map<Boolean, Student2> topScoreBySex2 = Stream.of(stuArr).
				collect(partitioningBy(Student2::isMale, collectingAndThen(maxBy(comparingInt(Student2::getScore)), Optional::get)));
		
		System.out.println("남학생 1등: "+topScoreBySex2.get(true));
		System.out.println("여학생 1등: "+topScoreBySex2.get(false));
		
		System.out.printf("%n4. 다중분할(성별 불합격자, 100점 이하)%n");
		Map<Boolean, Map<Boolean, List<Student2>>> failedStuBySex = Stream.of(stuArr).
				collect(partitioningBy(Student2::isMale, partitioningBy(s -> s.getScore() <= 100)));
		
		List<Student2> failedMaleStu = failedStuBySex.get(true).get(true);
		List<Student2> failedFemaleStu = failedStuBySex.get(false).get(true);
		
		for(Student2 s : failedMaleStu)
			System.out.println(s);
		for(Student2 s : failedFemaleStu)
			System.out.println(s);
	}//main

}

1. 단순분할(성별로 분할)
[나자바, 남, 1학년 1반, 300점]
[김자바, 남, 1학년 1반, 200점]
[남자바, 남, 1학년 2반, 100점]
[이자바, 남, 1학년 3반, 200점]
[나자바, 남, 2학년 1반, 300점]
[김자바, 남, 2학년 1반, 200점]
[남자바, 남, 2학년 2반, 100점]
[이자바, 남, 2학년 3반, 200점]
[김지미, 여, 1학년 1반, 250점]
[이지미, 여, 1학년 2반, 150점]
[안지미, 여, 1학년 2반,  50점]
[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[김지미, 여, 2학년 1반, 250점]
[이지미, 여, 2학년 2반, 150점]
[안지미, 여, 2학년 2반,  50점]
[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]

2. 단순분할 + 통계(성별 학생 수)
남학생 수: 8
여학생 수: 10

3. 단순불할 + 통계(성별 1등)
남학생 1등: Optional[[나자바, 남, 1학년 1반, 300점]]
여학생 1등: Optional[[김지미, 여, 1학년 1반, 250점]]
남학생 1등: [나자바, 남, 1학년 1반, 300점]
여학생 1등: [김지미, 여, 1학년 1반, 250점]

4. 다중분할(성별 불합격자, 100점 이하)
[남자바, 남, 1학년 2반, 100점]
[남자바, 남, 2학년 2반, 100점]
[안지미, 여, 1학년 2반,  50점]
[황지미, 여, 1학년 3반, 100점]
[안지미, 여, 2학년 2반,  50점]
[황지미, 여, 2학년 3반, 100점]


1. 단순분할(성별로 분할)
[나자바, 남, 1학년 1반, 300점]
[김자바, 남, 1학년 1반, 200점]
[남자바, 남, 1학년 2반, 100점]
[이자바, 남, 1학년 3반, 200점]
[나자바, 남, 2학년 1반, 300점]
[김자바, 남, 2학년 1반, 200점]
[남자바, 남, 2학년 2반, 100점]
[이자바, 남, 2학년 3반, 200점]
[김지미, 여, 1학년 1반, 250점]
[이지미, 여, 1학년 2반, 150점]
[안지미, 여, 1학년 2반,  50점]
[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[김지미, 여, 2학년 1반, 250점]
[이지미, 여, 2학년 2반, 150점]
[안지미, 여, 2학년 2반,  50점]
[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]

2. 단순분할 + 통계(성별 학생 수)
남학생 수: 8
여학생 수: 10

3. 단순불할 + 통계(성별 1등)
남학생 1등: Optional[[나자바, 남, 1학년 1반, 300점]]
여학생 1등: Optional[[김지미, 여, 1학년 1반, 250점]]
남학생 1등: [나자바, 남, 1학년 1반, 300점]
여학생 1등: [김지미, 여, 1학년 1반, 250점]

4. 다중분할(성별 불합격자, 100점 이하)
[남자바, 남, 1학년 2반, 100점]
[남자바, 남, 2학년 2반, 100점]
[안지미, 여, 1학년 2반,  50점]
[황지미, 여, 1학년 3반, 100점]
[안지미, 여, 2학년 2반,  50점]
[황지미, 여, 2학년 3반, 100점]


groupingBy()

Collector groupingBy(Function classifier)
Collector groupingBy(Function classifier, Collector downstream)
Collector groupingBy(Function classifier, Supplier mapFactory, Collector downstream)
  • 스트림을 n분할 한다.

예)



ex14_11

import java.util.*;
import java.util.function.*;
import java.util.stream.*;
import static java.util.stream.Collectors.*;
import static java.util.Comparator.*;

class Student3 {
	String name;
	boolean isMale; // 성별
	int hak;        // 학년
	int ban;        // 반
	int score;

	Student3(String name, boolean isMale, int hak, int ban, int score) { 
		this.name	= name;
		this.isMale	= isMale;
		this.hak   	= hak;
		this.ban	= ban;
		this.score 	= score;
	}

	String	getName() 	 { return name;    }
	boolean isMale()  	 { return isMale;  }
	int		getHak()   	 { return hak;	   }
	int		getBan()  	 { return ban;	   }
	int		getScore()	 { return score;   }

	public String toString() {
		return String.format("[%s, %s, %d학년 %d반, %3d점]", name, isMale ? "남" : "여", hak, ban, score);
	}

	enum Level {
		HIGH, MID, LOW
	}
}

public class Ex14_11 {

	public static void main(String[] args) {
		Student3[] stuArr = {
				new Student3("나자바", true,  1, 1, 300),	
				new Student3("김지미", false, 1, 1, 250),	
				new Student3("김자바", true,  1, 1, 200),	
				new Student3("이지미", false, 1, 2, 150),	
				new Student3("남자바", true,  1, 2, 100),	
				new Student3("안지미", false, 1, 2,  50),	
				new Student3("황지미", false, 1, 3, 100),	
				new Student3("강지미", false, 1, 3, 150),	
				new Student3("이자바", true,  1, 3, 200),	
				new Student3("나자바", true,  2, 1, 300),	
				new Student3("김지미", false, 2, 1, 250),	
				new Student3("김자바", true,  2, 1, 200),	
				new Student3("이지미", false, 2, 2, 150),	
				new Student3("남자바", true,  2, 2, 100),	
				new Student3("안지미", false, 2, 2,  50),	
				new Student3("황지미", false, 2, 3, 100),	
				new Student3("강지미", false, 2, 3, 150),	
				new Student3("이자바", true,  2, 3, 200)	
			};
		
		System.out.printf("1. 단순그룹화(반별로 그룹화)%n");
		//Map<반, stuArr>
		Map<Integer, List<Student3>> stuByBan = Stream.of(stuArr).
				collect(groupingBy(Student3::getBan));
		for(List<Student3> ban : stuByBan.values()) {
			for(Student3 s : ban)
				System.out.println(s);
		}
		
		System.out.printf("%n2. 단순그룹화(성적별로 그룹화)%n");
		//Map<성적수준enum, stuArr>
		Map<Student3.Level, List<Student3>> stuByLevel = Stream.of(stuArr).
				collect(groupingBy(s -> {
					if(s.getScore() >= 200)
						return Student3.Level.HIGH;
					else if(s.getScore() >= 100)
						return Student3.Level.MID;
					else
						return Student3.Level.LOW;
				}));
		
		TreeSet<Student3.Level> keySet = new TreeSet<>(stuByLevel.keySet());
		
		for(Student3.Level key : keySet) {
			System.out.println("["+key+"]");
			for(Student3 s : stuByLevel.get(key))
				System.out.println(s);
			System.out.println();
		}
		
		System.out.printf("%n3. 단순그룹화 + 통계(성적별 학생수)%n");
		//Map<성적수준enum, 학생 수>
		Map<Student3.Level, Long> stuCntByLevel = Stream.of(stuArr).
				collect(groupingBy(s -> {
					if(s.getScore() >= 200)
						return Student3.Level.HIGH;
					else if(s.getScore() >= 100)
						return Student3.Level.MID;
					else
						return Student3.Level.LOW;
				}, counting()));
		for(Student3.Level key : stuCntByLevel.keySet())
			System.out.printf("[%s] - %d명, ", key, stuCntByLevel.get(key));
		System.out.println();
		
		for(List<Student3> level : stuByLevel.values()) {
			System.out.println();
			for(Student3 s : level)
				System.out.println(s);
		}
		
		System.out.printf("%n4. 다중그룹화(학년별, 반별)%n");
		Map<Integer, Map<Integer, List<Student3>>> stuByHakAndBan = Stream.of(stuArr)
				.collect(groupingBy(Student3::getHak, groupingBy(Student3::getBan)));
		
		for(Map<Integer, List<Student3>> hak : stuByHakAndBan.values()) {
			for(List<Student3> ban : hak.values()) {
				System.out.println();
				for(Student3 s : ban)
					System.out.println(s);
			}
		}
		
		System.out.printf("%n5. 다중그룹화 + 통계(학년별, 반별 1등)%n");
		//Map<학년, Map<반, stuarr>>
		Map<Integer, Map<Integer, Student3>> topStuByHakAndBan = Stream.of(stuArr)
				.collect(groupingBy(Student3::getHak, 
						groupingBy(Student3::getBan,
								collectingAndThen(maxBy(comparingInt(Student3::getScore))
													, Optional::get)
								)
						));
		
		for(Map<Integer, Student3> ban : topStuByHakAndBan.values()) {
			for(Student3 s : ban.values())
				System.out.println(s);
		}
		
		System.out.printf("%n6. 다중그룹화 + 통계(학년별, 반별 성적그룹)%n");
		Map<String, Set<Student3.Level>> stuByScoreGroup = Stream.of(stuArr)
				.collect(groupingBy(s -> s.getHak() + "-" + s.getBan(),
								mapping(s -> {
									if(s.getScore() >= 200)
										return Student3.Level.HIGH;
									else if(s.getScore() >= 100)
										return Student3.Level.MID;
									else
										return Student3.Level.LOW;
									}, toSet())
								)
						);
		Set<String> keySet2 = stuByScoreGroup.keySet();
		
		for(String key : keySet2)
			System.out.println("["+key+"]"+stuByScoreGroup.get(key));
		
		
	}//main

}

1. 단순그룹화(반별로 그룹화)
[나자바, 남, 1학년 1반, 300점]
[김지미, 여, 1학년 1반, 250점]
[김자바, 남, 1학년 1반, 200점]
[나자바, 남, 2학년 1반, 300점]
[김지미, 여, 2학년 1반, 250점]
[김자바, 남, 2학년 1반, 200점]
[이지미, 여, 1학년 2반, 150점]
[남자바, 남, 1학년 2반, 100점]
[안지미, 여, 1학년 2반,  50점]
[이지미, 여, 2학년 2반, 150점]
[남자바, 남, 2학년 2반, 100점]
[안지미, 여, 2학년 2반,  50점]
[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[이자바, 남, 1학년 3반, 200점]
[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]
[이자바, 남, 2학년 3반, 200점]

2. 단순그룹화(성적별로 그룹화)
[HIGH]
[나자바, 남, 1학년 1반, 300점]
[김지미, 여, 1학년 1반, 250점]
[김자바, 남, 1학년 1반, 200점]
[이자바, 남, 1학년 3반, 200점]
[나자바, 남, 2학년 1반, 300점]
[김지미, 여, 2학년 1반, 250점]
[김자바, 남, 2학년 1반, 200점]
[이자바, 남, 2학년 3반, 200점]

[MID]
[이지미, 여, 1학년 2반, 150점]
[남자바, 남, 1학년 2반, 100점]
[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[이지미, 여, 2학년 2반, 150점]
[남자바, 남, 2학년 2반, 100점]
[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]

[LOW]
[안지미, 여, 1학년 2반,  50점]
[안지미, 여, 2학년 2반,  50점]


3. 단순그룹화 + 통계(성적별 학생수)
[MID] - 8명, [HIGH] - 8명, [LOW] - 2명, 

[이지미, 여, 1학년 2반, 150점]
[남자바, 남, 1학년 2반, 100점]
[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[이지미, 여, 2학년 2반, 150점]
[남자바, 남, 2학년 2반, 100점]
[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]

[나자바, 남, 1학년 1반, 300점]
[김지미, 여, 1학년 1반, 250점]
[김자바, 남, 1학년 1반, 200점]
[이자바, 남, 1학년 3반, 200점]
[나자바, 남, 2학년 1반, 300점]
[김지미, 여, 2학년 1반, 250점]
[김자바, 남, 2학년 1반, 200점]
[이자바, 남, 2학년 3반, 200점]

[안지미, 여, 1학년 2반,  50점]
[안지미, 여, 2학년 2반,  50점]

4. 다중그룹화(학년별, 반별)

[나자바, 남, 1학년 1반, 300점]
[김지미, 여, 1학년 1반, 250점]
[김자바, 남, 1학년 1반, 200점]

[이지미, 여, 1학년 2반, 150점]
[남자바, 남, 1학년 2반, 100점]
[안지미, 여, 1학년 2반,  50점]

[황지미, 여, 1학년 3반, 100점]
[강지미, 여, 1학년 3반, 150점]
[이자바, 남, 1학년 3반, 200점]

[나자바, 남, 2학년 1반, 300점]
[김지미, 여, 2학년 1반, 250점]
[김자바, 남, 2학년 1반, 200점]

[이지미, 여, 2학년 2반, 150점]
[남자바, 남, 2학년 2반, 100점]
[안지미, 여, 2학년 2반,  50점]

[황지미, 여, 2학년 3반, 100점]
[강지미, 여, 2학년 3반, 150점]
[이자바, 남, 2학년 3반, 200점]

5. 다중그룹화 + 통계(학년별, 반별 1등)
[나자바, 남, 1학년 1반, 300점]
[이지미, 여, 1학년 2반, 150점]
[이자바, 남, 1학년 3반, 200점]
[나자바, 남, 2학년 1반, 300점]
[이지미, 여, 2학년 2반, 150점]
[이자바, 남, 2학년 3반, 200점]

6. 다중그룹화 + 통계(학년별, 반별 성적그룹)
[1-1][HIGH]
[2-1][HIGH]
[1-2][MID, LOW]
[2-2][MID, LOW]
[1-3][MID, HIGH]
[2-3][MID, HIGH]



스트림의 변환




Ref

0개의 댓글