Optional<T>

Optional<T> 객체 생성하기

Optional<T> 객체 값 가져오기


Optionallant, OptionalLong, OptionalDouble


스트림의 최종연산 - forEach()
중간연산 : n번 가능, Stream을 반환
최종연산 : 1번 가능(스트림요소를 소모하기 때문에)
int, boolean, Optional 을 반환

스트림의 최종연산 - 조건검사

스트림의 최종연산 - reduce()


collect() 와 Collectors

스트림을 컬렉션, 배열로 변환

스트림을 리듀싱 - Collectors의 reducing()

스트림의 그룹화와 분할

import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.partitioningBy;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Stream;
class Student2{
String name;
boolean isMail; // 성별
int hak; // 학년
int ban; // 반
int score;
public Student2(String name, boolean isMail, int hak, int ban, int score) {
super();
this.name = name;
this.isMail = isMail;
this.hak = hak;
this.ban = ban;
this.score = score;
}
String getName() { return name; }
boolean isMale() { return isMail; }
int getHak() { return hak; }
int getBan() { return ban; }
int getScore() { return score; }
@Override
public String toString() {
return String.format("[ %s, %s, %d학년 %d반, %3d점 ]", name, isMail ? "남":"여", hak, ban, score);
}
//gorpingBy()에서 사용
enum Level { HIGH, MID, LOW } //성적을 상, 중, 하 3단계로 분류
}
public class ex14_50 {
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. 단순분할(성별로 분할");
// Stream.of() 이용하여 Student배열을 Stream으로 변환 후
// collect와 partitioningBy 이용하여 성별로 나눔.
//List<Student2> 에는 남자,여자 (true, false) 가 나뉘어서 들어감.
Map<Boolean, List<Student2>> stuBySex = Stream.of(stuArr)
.collect(partitioningBy(Student2::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.println("_____________________________________________________");
//________________________________________________________________________________
System.out.println("2. 단순분할 + 통계(성별 학생수)");
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.println("_____________________________________________________");
//________________________________________________________________________________
System.out.println("3. 단순분할 + 통계(성별 1등)");
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)); //Optional::get을주면 꺼내서 출력
System.out.println("여학생 1등 " + topScoreBySex2.get(false));
System.out.println("_____________________________________________________");
//________________________________________________________________________________
System.out.println("4. 다중분할(성별 불합격자, 100점 이하)");
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> fefailedMaleStu = failedStuBySex.get(false).get(true);
for(Student2 s : failedMaleStu) System.out.println(s);
for(Student2 s : fefailedMaleStu) System.out.println(s);
}
}

스트림의 그룹화 - groupingBy()

import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.maxBy;
import static java.util.stream.Collectors.toSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Stream;
class Student3{
String name;
boolean isMail; // 성별
int hak; // 학년
int ban; // 반
int score;
public Student3(String name, boolean isMail, int hak, int ban, int score) {
super();
this.name = name;
this.isMail = isMail;
this.hak = hak;
this.ban = ban;
this.score = score;
}
String getName() { return name; }
boolean isMale() { return isMail; }
int getHak() { return hak; }
int getBan() { return ban; }
int getScore() { return score; }
@Override
public String toString() {
return String.format("[ %s, %s, %d학년 %d반, %3d점 ]", name, isMail ? "남":"여", hak, ban, score);
}
//gorpingBy()에서 사용
enum Level { HIGH, MID, LOW } //성적을 상, 중, 하 3단계로 분류
}
public class ex14_51 {
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.println("1. 단순그룹화(반별로 그룹화)");
// Map<반, 해당학생>
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.println("____________________________________________");
//___________________________________________________________________
System.out.println("2. 단순그룹화(성적별로 그룹화)");
Map<Student3.Level, List<Student3>> stuByLevel1 = 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<>(stuByLevel1.keySet());
for(Student3.Level key : keySet) {
System.out.println("[" + key +"]");
for(Student3 s : stuByLevel1.get(key))
System.out.println(s);
System.out.println();
}
System.out.println("____________________________________________");
//___________________________________________________________________
System.out.println("3. 단순 그룹화 + 통계(성적별 학생수)");
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.println("["+key + "] : " + stuCntByLevel.get(key));
System.out.println("____________________________________________");
//___________________________________________________________________
System.out.println("4. 다중그룹화(학년별, 반별)");
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.println("____________________________________________");
//___________________________________________________________________
System.out.println("5. 다중 그룹화 + 통계(학년별, 반별 1등)");
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.println("____________________________________________");
//___________________________________________________________________
System.out.println("6. 다중 그룹화 + 통계(학년별, 반별 성적그룹)");
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));
}
}
}

스트림의 변환


출처 : 남궁성의 정석코딩
'Java의 정석' 카테고리의 다른 글
14장. 스트림(Stream) (0) | 2023.02.23 |
---|---|
14장. 람다식, 메서드참조 (0) | 2023.02.23 |
13장. 프로세스와 쓰레드 ( 동기화.. 등) (1) | 2023.02.21 |
12장. 어노테이션, 메타 어노테이션,타입 정의 및 요소 (0) | 2023.02.19 |
12장. 제네릭 - 와일드카드, 메서드, 제네릭형변환 (0) | 2023.02.18 |