티스토리 뷰

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 :

  1. 오류 난다. 컴파일러는 Number 아래 어떤 타입의 리스트인지 확신할 수 없기 때문이다. 예) 만약 List<Double>이라면 Integer을 넣으면 안되기에 아예 막는다.
  2. 오류 난다. 위 이유와 동일. 어떤 타입인지 확신할 수 없는 상태에서 함부로 넣을 수 없기에 생산자는 읽기 전용이다.
  3. 오류 난다. 어쩌다 List<Object>인데 그 안에 String 타입 값이 들어있다면 String 값에 Integer을 넣는 게 불가능하기 때문이다.
  4. 오류 안 난다. list.get()의 반환 타입은 최상위 부모 클래스인 Object이고 출력 함수는 Object 타입을 출력할 수 있으므로 상관이 없다.
  5. 오류 안 난다. 안전성 확보를 위해 가장 넓은 범위의 타입인 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 :

  1. 오류 안 난다.
  2. 오류 안 난다.
  3. 오류 난다. (value의 타입은 Integer인데 String타입을 넣었으므로)
  4. LinkedHashMap, HashMap 모두 키의 중복을 허용하지 않으므로 인덱스 2는 값 4로 바뀐다.
  5. {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
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함