[14-1] 메서드를 람다식으로 변환하여 아래의 표를 완성하시오.
사진 설명을 입력하세요.
답
- 0열 선택0열 다음에 열 추가
- 1열 선택1열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
- 2행 선택2행 다음에 행 추가
- 3행 선택3행 다음에 행 추가
- 4행 선택4행 다음에 행 추가
- 5행 선택5행 다음에 행 추가
- 6행 선택6행 다음에 행 추가
메서드
|
람다식
|
int max(int a, int b) {
return a > b ? a : b; } |
(int a, int b) -> a > b ? a : b
|
int printVar(String name, int i) {
System.out.println(name+"="+i); } |
(String name, int i) ->
System.out.println(name+"="+i) |
int square(int x) {
return x*x; } |
(int x) -> x*x
|
int roll() {
return (int)(Math.random() * 6); } |
() -> (int)(Math.random() * 6)
|
int sumArr(int[] arr) {
int sum = 0; for(int i : arr) sum += i; return sum; } |
(int[] arr) -> {
int sum = 0; for(int i : arr) sum += i; return sum; } |
int[] emptyArr() {
return new int[] {}; } |
() -> new int[]{}
|
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
참고
- 메서드 참조를 람다 표현식으로 변환하는 법
- 메서드의 매개변수가 없을 때: () -> { // 구현 }
- 메서드의 매개변수가 있을 때: (param1, param2) -> { // 구현 }
// 변환 전
interface SomeInterface {
void someMethod();
}
SomeInterface instance = new SomeInterface() {
@Override
public void someMethod() {
// 메서드 구현
}
};
// 변환 후
SomeInterface instance = () -> {
// 메서드 구현
};
[14-2] 람다식을 메서드 참조로 변환하여 아래의 표를 완성하시오.
(변환이 불가능한 경우, '변환불가'라고 적어야함.)
사진 설명을 입력하세요.
답
- 0열 선택0열 다음에 열 추가
- 1열 선택1열 다음에 열 추가
- 0행 선택0행 다음에 행 추가
- 1행 선택1행 다음에 행 추가
- 2행 선택2행 다음에 행 추가
- 3행 선택3행 다음에 행 추가
- 4행 선택4행 다음에 행 추가
- 5행 선택5행 다음에 행 추가
- 6행 선택6행 다음에 행 추가
- 7행 선택7행 다음에 행 추가
- 8행 선택8행 다음에 행 추가
- 9행 선택9행 다음에 행 추가
- 10행 선택10행 다음에 행 추가
- 11행 선택11행 다음에 행 추가
- 12행 선택12행 다음에 행 추가
- 13행 선택13행 다음에 행 추가
람다식
|
메서드 참조
|
(String s) -> s.length()
|
String :: length
|
() -> new int[]{}
|
int[] :: new
|
arr -> Arrays.stream(arr)
|
Arrays :: stream
|
(String str1, String str2) -> strl.equals(str2)
|
String :: equals
|
(a, b) -> Integer.compare(a, b)
|
Integer :: compare
|
(String kind, int num) -> new Card(kind, num)
|
Card :: new
|
(x) -> System.out.println(x)
|
System.out :: println
|
() -> Math.random()
|
Math :: random
|
(str) -> str.toUpperCase()
|
String :: toUpperCase
|
() -> new NullPointerException()
|
NullPointerException :: new
|
(Optional opt) -> opt.get()
|
Optional :: get
|
(StringBuffer sb, String s) -> sb.append(s)
|
StringBuffer :: append
|
(String s) -> System.out.println(s)
|
System.out :: println
|
- 셀 병합
- 행 분할
- 열 분할
- 너비 맞춤
- 삭제
참고
- 메서드 참조를 람다 표현식으로 변환하는 법
- 메서드의 매개변수가 없을 때:
SomeInterface instance = new SomeInterface() {
@Override
public void someMethod() {
// 메서드 구현
}
};
- 메서드의 매개변수가 있을 때:
interface SomeInterface {
void someMethod(Type1 param1, Type2 param2);
}
SomeInterface instance = new SomeInterface() {
@Override
public void someMethod(Type1 param1, Type2 param2) {
// 메서드 구현
}
};
변환 전/후
// 변환 전
SomeInterface instance = () -> {
// 메서드 구현
};
// 변환 후
interface SomeInterface {
void someMethod();
}
SomeInterface instance = new SomeInterface() {
@Override
public void someMethod() {
// 메서드 구현
}
};
[14-3] 아래의 괄호안에 알맞은 함수형 인터페이스는?
( ) f; //함수형 인터페이스 타입의 참조변수 f를 선언
f = (int a, int b) -> a > b ? a : b;
a. Function
b. BiFunction
c. Predicate
d. BinaryOperator
e. IntFunction
답
d
풀이
BinaryOperator :
동일한 유형의 두 인수를 받아 동일한 유형의 결과를 반환하는 연산을 나타내는 함수형 인터페이스
(int a, int b) -> a > b ? a : b와 같은 람다 표현식에 적합
Function: 하나의 인수를 받아 결과를 반환하는 함수형 인터페이스. 인수와 반환 유형이 다를 수 있다.
BiFunction: 두 개의 인수를 받아 결과를 반환하는 함수형 인터페이스. 인수와 반환 유형이 다를 수 있다.
Predicate: 하나의 인수를 받아 불리언 값을 반환하는 함수형 인터페이스.
IntFunction: 정수를 받아 결과를 반환하는 함수형 인터페이스. 결과 유형은 다를 수 있다.
[14-4] 문자열 배열 strArr의 모든 문자열의 길이를 더한 결과를 출력하시오.
import java.util.stream.Stream;
public class Exercise14_4 {
public static void main(String[] args) {
String[] strArr = {"aaa","bb","c","dddd"};
Stream<String> strStream = Stream.of(strArr);
// int sum = strStream.mapToInt(s->s.length()).sum();
int sum = strStream.mapToInt(String::length).sum();
System.out.println("sum="+sum);
}
}
sum = 10
답
방법1. 람다 표현식
방법2. 메서드 참조
import java.util.stream.Stream;
public class Exercise14_4 {
public static void main(String[] args) {
String[] strArr = {"aaa","bb","c","dddd"};
Stream<String> strStream = Stream.of(strArr);
// 람다 표현식을 사용하여 문자열의 길이를 합산
// int sum = strStream.mapToInt(s -> s.length()).sum();
// 메서드 참조를 사용하여 문자열의 길이를 합산
int sum = strStream.mapToInt(String::length).sum();
System.out.println("sum=" + sum);
}
}
[14-5] 문자열 배열 strArr의 문자열 중에서 가장 긴 것의 길이를 출력하시오.
4
답
import java.util.Comparator;
import java.util.stream.Stream;
public class Exercise14_5 {
public static void main(String[] args) {
String[] strArr = {"aaa", "bb", "c", "dddd"};
Stream<String> strStream = Stream.of(strArr);
strStream.map(String::length) // 문자열의 길이를 매핑
.sorted(Comparator.reverseOrder()) // 길이로 역순 정렬
.limit(1) // 가장 긴 문자열의 길이를 가져옴
.forEach(System.out::println); // 출력
}
}
풀이
1. Stream.of(strArr)를 사용하여 문자열 배열 strArr로부터 스트림을 생성.
2. map(String::length)를 사용하여 각 문자열을 그 길이로 매핑.
3. sorted(Comparator.reverseOrder())를 사용하여 길이를 역순으로 정렬.
4. limit(1)를 사용하여 가장 긴 문자열의 길이만 가져옴.
5. forEach(System.out::println)를 사용하여 그 길이를 출력.
[14-6] 임의의 로또번호(1~45)를 정렬해서 출력하시오.
1
20
25
33
35
42
답
import java.util.Random;
public class Exercise14_6 {
public static void main(String[] args) {
new Random().ints(1,46) // 1~45사이의 정수(46은 포함안됨)
.distinct() // 중복제거
.limit(6) // 6개만
.sorted() // 정렬
.forEach(System.out::println); //화면에 출력
}
}
풀이
1. new Random().ints(1, 46):
Random 객체를 생성하여 ints(int origin, int bound) 메서드를 호출.
1부터 45(46 미포함) 사이의 무한 스트림을 생성.
2. .distinct():
스트림에서 중복된 요소를 제거.
중복되지 않는 고유한 숫자들만 남김.
3. .limit(6):
스트림의 크기를 제한하여 최대 6개의 요소만 포함.
중복이 제거된 후 6개의 숫자만 남음.
4. .sorted():
스트림의 요소를 오름차순으로 정렬.
숫자들이 정렬됨.
5. .forEach(System.out::println):
스트림의 각 요소를 순차적으로 출력.
최종적으로 생성된 6개의 숫자가 화면에 출력됨.
[14-7] 두 개의 주사위를 굴려서 나온 눈의 합이 6인 경우를 모두 출력하시오.
[Hint] 배열을 사용하시오.
[1,5]
[2,4]
[3,3]
[4,2]
[5,1]
답
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class Exercise14_7 {
public static void main(String[] args) {
Stream<Integer> die = IntStream.rangeClosed(1, 6).boxed();
die.flatMap(i -> Stream.of(1, 2, 3, 4, 5, 6).map(i2 -> new int[] { i, 12 }))
.filter(iArr -> iArr[0] + iArr[1] == 6)
.forEach(iArr -> System.out.println(Arrays.toString(iArr)));
}
}
풀이
1. Stream<Integer> die = IntStream.rangeClosed(1, 6).boxed();
1부터 6까지의 정수를 포함하는 스트림을 생성.
주사위의 눈 값을 스트림으로 변환.
2. die.flatMap(i -> IntStream.rangeClosed(1, 6).mapToObj(j -> new int[] { i, j }));
첫 번째 주사위의 값을 i로 사용하여 두 번째 주사위의 값을 j로 생성.
두 주사위의 값을 배열로 만들어 스트림으로 변환.
3. .filter(arr -> arr[0] + arr[1] == 6)
두 주사위의 합이 6이 되는 배열만 필터링.
4. .forEach(arr -> System.out.println(Arrays.toString(arr)));
조건에 맞는 배열을 출력.
[14-8] 다음은 불합격(150점 미만)한 학생의 수를 남자와 여자로 구별하여 출력하는 프로그램이다. (1)에 알맞은 코드를 넣어 완성하시오.
불합격[남자]:2명
불합격[여자]:4명
답
import java.util.*;
import java.util.stream.Collectors;
class Student {
String name;
boolean isMale; // 성별
int hak; // 학년
int ban; // 반
int score;
Student(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);
}
// groupingBy()에서 사용 성적을 상,중,하 세 단계로 분류
enum Level {
HIGH, MID, LOW
}
}
class Exercise14_8 {
public static void main(String[] args) {
Student[] stuArr = {
new Student("나자바", true, 1, 1, 300),
new Student("김지미", false, 1, 1, 250),
new Student("김자바", true, 1, 1, 200),
new Student("이지미", false, 1, 2, 150),
new Student("남자바", true, 1, 2, 100),
new Student("안지미", false, 1, 2, 50),
new Student("황지미", false, 1, 3, 100),
new Student("강지미", false, 1, 3, 150),
new Student("이자바", true, 1, 3, 200),
new Student("나자바", true, 2, 1, 300),
new Student("김지미", false, 2, 1, 250),
new Student("김자바", true, 2, 1, 200),
new Student("이지미", false, 2, 2, 150),
new Student("남자바", true, 2, 2, 100),
new Student("안지미", false, 2, 2, 50),
new Student("황지미", false, 2, 3, 100),
new Student("강지미", false, 2, 3, 150),
new Student("이자바", true, 2, 3, 200)
};
Map<Boolean, Map<Boolean, Long>> failedStuBySex =
Arrays.stream(stuArr)
.filter(s -> s.getScore() < 150)
.collect(Collectors.partitioningBy(Student::isMale,
Collectors.partitioningBy(s -> s.getScore() < 150, Collectors.counting())));
long failedMaleStuNum = failedStuBySex.get(true).get(true);
long failedFemaleStuNum = failedStuBySex.get(false).get(true);
System.out.println("불합격[남자]:" + failedMaleStuNum + "명");
System.out.println("불합격[여자]:" + failedFemaleStuNum + "명");
}
}
풀이
1. Arrays.stream(stuArr)
stuArr 배열을 스트림으로 변환
2. .filter(s -> s.getScore() < 150)
점수가 150점 미만인 학생들만 필터링
3. .collect(Collectors.partitioningBy(Student::isMale, Collectors.partitioningBy(s -> s.getScore() < 150, Collectors.counting())))
첫 번째 partitioningBy는 학생의 성별(isMale)을 기준으로 학생들을 두 그룹으로 나눔
두 번째 partitioningBy는 점수가 150점 미만인지를 기준으로 다시 두 그룹으로 나눔
counting()을 사용해 각 그룹의 학생 수를 셈
4. failedStuBySex.get(true).get(true)와 failedStuBySex.get(false).get(true)
[14-9] 다음은 각 반별 총점을 학년 별로 나누어 출력하는 프로그램이다. (1)에 알맞은 코드를 넣어 완성하시오.
답
import java.util.*;
import java.util.stream.Collectors;
class Student {
String name;
boolean isMale; // 성별
int hak; // 학년
int ban; // 반
int score;
Student(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
}
}
class Exercise14_9 {
public static void main(String[] args) {
Student[] stuArr = {
new Student("나자바", true, 1, 1, 300),
new Student("김지미", false, 1, 1, 250),
new Student("김자바", true, 1, 1, 200),
new Student("이지미", false, 1, 2, 150),
new Student("남자바", true, 1, 2, 100),
new Student("안지미", false, 1, 2, 50),
new Student("황지미", false, 1, 3, 100),
new Student("강지미", false, 1, 3, 150),
new Student("이자바", true, 1, 3, 200),
new Student("나자바", true, 2, 1, 300),
new Student("김지미", false, 2, 1, 250),
new Student("김자바", true, 2, 1, 200),
new Student("이지미", false, 2, 2, 150),
new Student("남자바", true, 2, 2, 100),
new Student("안지미", false, 2, 2, 50),
new Student("황지미", false, 2, 3, 100),
new Student("강지미", false, 2, 3, 150),
new Student("이자바", true, 2, 3, 200)
};
Map<Integer, Map<Integer, Long>> totalScoreByHakAndBan =
Arrays.stream(stuArr)
.collect(Collectors.groupingBy(
Student::getHak,
Collectors.groupingBy(
Student::getBan,
Collectors.summingLong(Student::getScore)
)
));
for (Object e : totalScoreByHakAndBan.entrySet()) {
System.out.println(e);
}
}
}
풀이
1. Arrays.stream(stuArr)
stuArr 배열을 스트림으로 변환
2. .collect(Collectors.groupingBy(Student::getHak, Collectors.groupingBy(Student::getBan, Collectors.summingLong(Student::getScore))))
첫 번째 groupingBy는 학생들을 학년(getHak)별로 그룹화
두 번째 groupingBy는 학년 내에서 학생들을 반(getBan)별로 그룹화
summingLong(Student::getScore)를 사용해 각 그룹의 총점을 계산
3. totalScoreByHakAndBan.entrySet()을 순회하며 각 학년과 반의 총점을 출력
'개념' 카테고리의 다른 글
[JAVA의 정석] Chapter16_연습문제 (1) | 2024.12.15 |
---|---|
[JAVA의 정석] Chapter15_연습문제 (0) | 2024.12.15 |
[JAVA의 정석] Chapter13_연습문제 (0) | 2024.12.15 |
[JAVA의 정석] Chapter12_연습문제 (2) | 2024.12.15 |
[JAVA의 정석] Chapter11_연습문제 (0) | 2024.12.15 |