티스토리 뷰
Q1. 주석 처리된 질문들에 대해 답하시오.
//생산자
public void printNumbers(List <? extends Number> list){
for(Number n : list) {
System.out.println(n);
}
//1. list.add(new Integer(1)); 을 하면 오류가 날까?
//2. list.add(new Number(1)); 을 하면 오류가 날까?
//소비자
public void addNumbers(List <? super Integer> list){
list.add(10);
//3. Integer num = list.get(0); 을 하면 오류가 날까?
//4. System.out.println(list.get(0)); 을 하면 오류가 날까?
//5. Object obj = list.get(1); 을 하면 오류가 날까?
A1 :
- 오류 난다. 컴파일러는 Number 아래 어떤 타입의 리스트인지 확신할 수 없기 때문이다. 예) 만약 List<Double>이라면 Integer을 넣으면 안되기에 아예 막는다.
- 오류 난다. 위 이유와 동일. 어떤 타입인지 확신할 수 없는 상태에서 함부로 넣을 수 없기에 생산자는 읽기 전용이다.
- 오류 난다. 어쩌다 List<Object>인데 그 안에 String 타입 값이 들어있다면 String 값에 Integer을 넣는 게 불가능하기 때문이다.
- 오류 안 난다. list.get()의 반환 타입은 최상위 부모 클래스인 Object이고 출력 함수는 Object 타입을 출력할 수 있으므로 상관이 없다.
- 오류 안 난다. 안전성 확보를 위해 가장 넓은 범위의 타입인 Object로 반환된 것을 Object 타입에 넣는 것은 괜찮다.
List <T> list : get() 사용 시 T 타입으로 반환
List <? extends T> list : 가장 넓은 범위인 T 타입으로 반환
List <? super T> list : 가장 넓은 범위인 Object 타입으로 반환
List <?> list : 가장 넓은 범위인 Object 타입으로 반환
Q2. 다음 PECS원칙과 관련된 코드를 보고, 클래스 다이어그램을 그려본 후, 컴파일러가 T를 APPLE로 추론하는 이유에 대해 설명하시오.
public class Apple extends Fruit {
public String toString() {return "사과";}
}
class Fruit {
public String toString() {return "과일"; }
}
public class GoldenApple extends Apple{
public String toString() {return "황금사과";}
}
public class GenericLab {
public static void main(String[] args) {
List <GoldenApple> goldenApples = new ArrayList<>();
goldenApples.add(new GoldenApple());//황금사과 바구니
List <Apple> apples = new ArrayList<>();//사과 바구니
apples.add(new Apple());
List <Fruit> fruits = new ArrayList<>();//과일바구니
List <Object> objects = new ArrayList<>();//잡동사니 바구니
System.out.println("복사 전 fruits: "+fruits);
System.out.println("복사 전 objects: "+objects);
System.out.println("-------------------------------------");
//시나리오 1 : 황금사과를 과일 바구니에 복사, T는 Apple로 추론됨
System.out.println("황금사과 -> 과일 바구니로 복사");
copy(goldenApples, fruits);
System.out.println("복사 후 fruits: "+fruits);
System.out.println();
//시나리오 2 : 사과를 object 바구니에 복사, T는 Apple로 추론됨
System.out.println("사과 -> 최상위 바구니로 복사");
copy(apples, objects);
System.out.println("복사 후 objects: "+objects);
}
public static <T> void copy(List<? extends T> src, List<? super T> dest) {
for(T item : src) {
dest.add(item);
}
}
}
A2 :

src리스트의 타입은 : T 아래로 들어올 수 있는데, GoldenApple이 들어왔으니까 GoldenApple의 상위 타입이어야 한다.(Apple, Fruit, Object 중 하나)
dest리스트의 타입은 : T 위로 들어올 수 있는데 List<Fruit>이 들어왔으니까 Fruit의 하위타입(GoldenApple, Apple, Fruit 중 하나)
이 중 가장 구체적인(가장 하위클래스인) Apple로 T를 추론한다.
Q3. 출력 방식 4개가 무엇인지 쓰고, 실제로 코드를 작성해보시오.
import java.util.*;
public class Main {
public static void main(String[] args){
List <Integer> list = new LinkedList <>();
list.add(1);
list.add(2);
list.add(3);
//출력 방식 1: _____________
//출력 방식 2: _____________
//출력 방식 3: _____________
//출력 방식 4: _____________
A3 :
//출력 방식 1: 단순 for문
for(int i=0; i<list.size(); i++){
System.out.println(list.get(i));
}
//출력 방식 2: for-Each문
for(int i : list) {
System.out.println(i);
}
//출력 방식 3: 이터레이터 사용하기
Iterator <Integer> num = list.listIterator();
while(num.hasNext()) {
System.out.println(num.next());
}
//출력 방식 4: forEach 람다식 사용
list.forEach(a->System.out.println(a));
Q4. 다음 질문에 답하시오.
Map <Integer, Integer> map = new LinkedHashMap<>();
map.put(1, null); //1. 오류가 날까요?
map.put(null, 1); //2. 오류가 날까요?
map.put(null, "1");//3. 오류가 날까요?
map.put(2, 3);
map.put(2, 4);//4. 같은 키에 후에 다른 값을 put하면 어떻게 될까요?
System.out.println(map);
//5. 출력결과를 예상해보세요.
A4 :
- 오류 안 난다.
- 오류 안 난다.
- 오류 난다. (value의 타입은 Integer인데 String타입을 넣었으므로)
- LinkedHashMap, HashMap 모두 키의 중복을 허용하지 않으므로 인덱스 2는 값 4로 바뀐다.
- {1=null, null=1, 2=4}
Q5. 짱구는 값1 = “나는”, 값2 = “나는”, 값3=”테일러”, 값4=”테일러”, 값5=”스위프트를”, 값6=”좋아해” 이 6개 값을 넣어서 출력이 “나는 테일러 스위프트를 좋아해” 라고 나오는 컬렉션을 찾고 있다. 해당하는 컬렉션의 이름을 말하고, 아래 코드를 작성해 직접 구현해 보시오.
public class Main{
public static void main(String[] args){
String value1 = "나는";
String value2 = "나는";
String value3 = "테일러";
String value4 = "테일러";
String value5 = "스위프트를";
String value6 = "좋아해";
//사용해야 하는 컬렉션의 이름 : _______________
//이후로 코드를 작성해 구현하세요.
}
}
A5:
public class Main{
public static void main(String[] args){
String value1 = "나는";
String value2 = "나는";
String value3 = "테일러";
String value4 = "테일러";
String value5 = "스위프트를";
String value6 = "좋아해";
//사용해야 하는 컬렉션의 이름 : LinkedHashSet
//이유 : 중복을 없애기에 set을 써야하고, 순서를 유지해야 하므로 LinkedHashSet이 적합하다.
//이후로 코드를 작성해 구현하세요.
Set <String> lhs = new LinkedHashSet<>();
lhs.add(value1);
lhs.add(value2);
lhs.add(value3);
lhs.add(value4);
lhs.add(value5);
lhs.add(value6);
//출력
lhs.forEach(s->System.out.print(s+" "));
}
}'학교 강의 > Java프로그래밍및실습2' 카테고리의 다른 글
| [Thread] 문제 만들기 (0) | 2025.09.30 |
|---|---|
| [Thread] JAVA에서의 Thread (0) | 2025.09.25 |
| 배틀 리팩토링 - 모듈화를 중심으로 (2) | 2025.09.13 |
| 0910 자프실2 수업 복기 (0) | 2025.09.11 |
| 0908 자프실2 (0) | 2025.09.09 |
