Pair<A, B> 레코드를 만들고, 두 요소를 바꾼 Pair<B, A> 를 반환하는 swap() 메서드와, 첫 번째 요소를 변환하는 <C> Pair<C, B> mapFirst(Function<? super A, ? extends C> f) 메서드를 작성하세요. Pair.of("won", 1000) 으로 만들어 두 메서드를 호출한 결과를 출력하세요.
import java.util.function.Function;
public class Ex1 {
record Pair<A, B>(A first, B second) {
static <A, B> Pair<A, B> of(A a, B b) { return new Pair<>(a, b); }
Pair<B, A> swap() { return new Pair<>(second, first); }
<C> Pair<C, B> mapFirst(Function<? super A, ? extends C> f) {
return new Pair<>(f.apply(first), second);
}
}
public static void main(String[] args) {
Pair<String, Integer> p = Pair.of("won", 1000);
System.out.println(p.swap()); // Pair[first=1000, second=won]
System.out.println(p.mapFirst(String::length)); // Pair[first=3, second=1000]
}
}
// 출력:
// Pair[first=1000, second=won]
// Pair[first=3, second=1000]List<? extends Number> 두 개를 받아 각 인덱스의 합을 List<Double> 로 돌려주는 static List<Double> zipSum(List<? extends Number> a, List<? extends Number> b) 를 작성하세요. 길이가 다르면 짧은 쪽 기준입니다.
zipSum(List.of(1, 2, 3), List.of(0.5, 0.5)) 의 결과를 출력하세요. 그리고 왜 파라미터를 List<Number> 로 선언하면 List.of(1, 2, 3) 을 넘길 수 없는지 주석으로 설명하세요.
import java.util.*;
public class Ex2 {
// List<Number> 로 선언하면 List<Integer> 는 불공변 때문에 대입 불가.
// 읽기만 하므로 PECS 의 producer → ? extends Number.
static List<Double> zipSum(List<? extends Number> a, List<? extends Number> b) {
int n = Math.min(a.size(), b.size());
List<Double> out = new ArrayList<>(n);
for (int i = 0; i < n; i++) out.add(a.get(i).doubleValue() + b.get(i).doubleValue());
return out;
}
public static void main(String[] args) {
System.out.println(zipSum(List.of(1, 2, 3), List.of(0.5, 0.5)));
}
}
// 출력:
// [1.5, 2.5]sealed interface Shape permits Circle, Rect 와 두 record 를 정의하고, <T extends Shape> T largest(List<T> shapes) 를 작성하세요. 넓이는 Shape 에 double area() 추상 메서드를 두고 각 record 가 구현합니다.
largest(List.of(new Circle(1), new Circle(2))) 의 반환 타입이 Circle 로 추론되어 radius() 를 바로 호출할 수 있음을 보이세요.
import java.util.*;
public class Ex3 {
sealed interface Shape permits Circle, Rect { double area(); }
record Circle(double radius) implements Shape { public double area() { return Math.PI * radius * radius; } }
record Rect(double w, double h) implements Shape { public double area() { return w * h; } }
// 반환 타입이 T 이므로 List<Circle> 을 넘기면 Circle 이 돌아온다 (Shape 로 넓어지지 않음)
static <T extends Shape> T largest(List<T> shapes) {
T best = shapes.get(0);
for (T s : shapes) if (s.area() > best.area()) best = s;
return best;
}
public static void main(String[] args) {
Circle c = largest(List.of(new Circle(1), new Circle(2)));
System.out.println("radius = " + c.radius());
Shape any = largest(List.of(new Circle(1), new Rect(3, 3))); // T = Shape
System.out.println(any);
}
}
// 출력:
// radius = 2.0
// Rect[w=3.0, h=3.0]