## 24. 제네릭을 사용하여 타입을 파라미터로 다루기
- ArrayList, LinkedList, Stack, Queue에 제네릭 적용하기
- T[] toArray(T[]) 메서드 추가하기
ArrayList.java
ㄴ 어떤 타입을 받을 지를 일단 <what> 으로 설정
List.java
=>
ㄴ what 으로 넘겨받도록 해줌
실제 java api 에 정의되어있는 제네릭은 what 으로 설정한 부분을 T 로 해줌
List.java
=>
ㄴ 관례적으로 T, E, K, N, V, R 을 사용
타입인자 | 설명 |
<T> | Type |
<E> | Element |
<K> | Key |
<N> | Number |
<V> | Value |
<R> | Result |
ArrayList.java
ㄴ 제네릭 타입 E 추가
ArrayList.java
ArrayList.java
ㄴ 리턴타입이 E 로 ]되어있으므로 (E) 로 명시적 형변환
=>
ArrayList.java
=>
ArrayList.java
ㄴ 컴파일러의 경고를 억제하는 역할
ㄴ 형변환 시 발생할 수 있는 경고를 억제하고 있음
ArrayList.java
ArrayList.java
ㄴ remove(int index) 메서드에 제네릭 타입 E 추가
ArrayList.java
ㄴ 리턴타입이 E 로 ]되어있으므로 (E) 로 명시적 형변환
ArrayList.java
ㄴ 컴파일러의 경고를 억제하는 역할
ㄴ 형변환 시 발생할 수 있는 경고를 억제하고 있음
ㄴ remove(int index) 메서드에 제네릭 타입 E 추가
ㄴ indexOf(Object obj) 메서드에 제네릭 타입 E 추가
App.java
=>
App.java
ㄴ 어떤 타입으로 할 것인지 정해줌
=> 여기서는 Member 와 Item 타입으로 지정해줌
=> 해당 코드에서 뒤쪽의 Member 는 제거해줘도됨
MemberAddListener.java
ㄴ MemberAddListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받고, 상위 클래스인 AbstractMemberListener의 생성자에 이 파라미터를 전달 받도록 함
=> MemberAddListener 클래스는 AbstractMemberListener 클래스의 기능을 상속받으면서, List<Member> 타입의 리스트를 사용할 수 있게 됨
AbstractMemberListener.java
ㄴ MemberAddListener 클래스의 수퍼 클래스인 AbstractMemberListener 클래스에서도 타입 List<Member> 로 변경해줌
AbstractMemberListener.java
ㄴ AbstractMemberListener 클래스에서 list 필드의 타입은 List<Member>
=> 제네릭으로 선언된 리스트이며, 타입 인자로 Member를 명시했으므로 Member m = (Member) this.list.get(i); 에서 형변환 필요 없어짐
MemberDeleteListener.java
ㄴ MemberDeleteListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받도록 함
MemberDetailListener.java
ㄴ MemberDetailListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받도록 함
MemberListListener.java
ㄴ MemberDeleteListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받도록 함
=> list는 제네릭으로 선언된 리스트이며, 타입 인자로 Member를 명시했으므로 Member m = (Member) this.list.get(i); 에서 형변환 필요 없어짐
MemberUpdateListener.java
ㄴ MemberUpdateListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받도록 함
LinkedList.java
ㄴ LinkedList 클래스에 제네릭 타입 E 추가
LinkedList 클래스에도 제네릭 타입 적용해주기
LinkedList.java
=> cursor.value 도 형변환 필요
LinkedList.java
ㄴ Node 클래스도 제네릭 타입을 추가해줌
=> LinkedList 클래스의 인스턴스를 생성할 때 지정된 모든 타입의 요소를 보관할 수 있음
Node 클래스와 관련된 코드 수정
LinkedList.java
LinkedList.java
LinkedList.java
LinkedList.java
=>
LinkedList.java
ㄴ cursor 가 Node<E> 타입이므로 SuppressWarnings("unchecked") 어노테이션 제거해도 되고, 형변환도 안 해줘도 됨
LinkedList.java
LinkedList.java
=>
LinkedList.java
=>
LinkedList.java
ㄴ cursor 가 E 타입이므로 SuppressWarnings("unchecked") 어노테이션 제거해도 되고, 형변환도 안 해줘도 됨
LinkedList.java
ㄴ 숫자 타입을 받기 때문에 Integer 타입으로 명시
App.java
=>
ㄴ 어떤 타입으로 할 것인지 정해줌
=> 여기서는 Board 타입으로 지정해줌
=> 해당 코드에서 뒤쪽의 Board 는 제거해줘도됨
BoardAddListener.java
ㄴ BoardAddListener 클래스의 생성자는 List<Board> 타입의 파라미터를 받고, 상위 클래스인 AbstractBoardListener의 생성자에 이 파라미터를 전달 받도록 함
=> BoardAddListener 클래스는 AbstractBoardListener 클래스의 기능을 상속받으면서, List<Board> 타입의 리스트를 사용할 수 있게 됨
AbstractBoardListener.java
ㄴ BoardAddListener 클래스의 수퍼 클래스인 AbstractBoardListener 클래스에서도 타입 List<Board> 로 변경해줌
AbstractBoardListener.java
ㄴ Board b = (Board) this.list.get(i); -> Board b = this.list.get(i);
=> list 는 제네릭으로 선언된 리스트이며, 타입 인자로 Board를 명시했으므로 형변환 필요 없음
BoardListListener.java
ㄴ MemberDeleteListener 클래스의 생성자는 List<Member> 타입의 파라미터를 받도록 함
BoardDetailListener.java
ㄴ BoardDetailListener 클래스의 생성자는 List<Board> 타입의 파라미터를 받도록 함
BoardUpdateListener.java
ㄴ BoardUpdateListener 클래스의 생성자는 List<Board> 타입의 파라미터를 받도록 함
BoardDeleteListener.java
ㄴ BoardDeleteListener 클래스의 생성자는 List<Board> 타입의 파라미터를 받도록 함
=> Item 도 Member, Board 와 마찬가지로 수정
Java 17 api 참고
List.java
ㄴ T[] 배열 타입의 toArray 메서드는 제네릭 메서드로, 주어진 배열에 리스트의 요소를 복사하여 반환하는 기능을 수행함
=> 주어진 배열 arr에 리스트의 요소를 복사하여 반환
=> 제네릭 메서드인 toArray는 타입 매개변수 <T>를 가지고 있음
=> 이를 통해 메서드 호출 시에 반환할 배열의 타입을 지정할 수 있음
=> toArray 메서드를 호출할 때 타입을 정함
ArrayList.java
ㄴ newInstance 를 이용하여 새로운 배열 생성
=>
ArrayList.java
ㄴ arr.getClass().getComponentType()은 arr 배열의 컴포넌트 타입을 가져오는 부분
ㄴ arr.getClass()는 arr 배열의 클래스를 가져오는 부분
ㄴ getComponentType()은 해당 클래스의 컴포넌트 타입을 반환
=> 이렇게 가져온 컴포넌트 타입을 기반으로 새로운 배열이 생성됨
ㄴ Array.newInstance(arr.getClass().getComponentType(), this.length)는 arr 배열과 동일한 컴포넌트 타입과 길이를 갖는 새로운 배열을 생성하여 values 변수에 할당하는 부분
=> 이렇게 생성된 배열은 제네릭 타입 T의 배열로 캐스팅되어 반환됨
=>
ArrayList.java
ㄴ Array.newInstance를 사용하여 새로운 배열을 생성하고, 제네릭 캐스트를 수행하여 배열의 타입을 맞춤
ㄴ 또한, 리스트의 요소를 순회하며 배열에 복사하고, 최종적으로 배열을 반환
v
ArrayList.java
ㄴ 테스트 하기 위한 작업
Test.java
ㄴ bitcamp.util 패키지에 Test.java 파일 생성하여 테스트
=>
Test.java
ㄴ bitcamp.util 패키지에 있는 Test.java 파일에서 테스트
=>
Test.java
=>
Test.java
ㄴ 받는 문자열은 4개인데, arr 문자열 배열의 size 를 2로 했을 경우 ArrayIndexOutOfBoundsException 발생
=>
Test.java
ㄴ 받는 문자열은 4개인데, arr 문자열 배열의 size 를 6으로 했을 경우 빈 공간에 null 값이 채워짐
ArrayList.java
=>
ArrayList.java
=>
ArrayList.java
ㄴ 파라미터로 받은 배열이 목록의 개수보다 작다면, 새 배열을 만들어 저장
ㄴ 파라미터로 받은 배열이 목록에 저장된 개수와 같거나 크다면, 파라미터로 받은 배열을 그대로 사용
=>
ArrayList.java
=>
ArrayList.java
=>
Test.java
=>
Test.java
ArrayList 클래스에 생성한 toArray 메서드를 LinkedList 클래스로 복사
LinkedList.java
length -> size 로 Rename
LinkedList.java
=>
LinkedList.java
ㄴ 복사하여 T[] toArray(T[] arr) 메서드에 for 문 대신 넣어주기
=>
LinkedList.java
ㄴ 형변환 필요
Stack.java
ㄴ Stack 클래스에 제네릭 타입 E 추가
메서드별로 제네릭 적용
Stack.java
Stack.java
ㄴ 문자열 타입을 받기 때문에 String 타입으로 명시
Queue.java
ㄴ Queue 클래스에 제네릭 타입 E 추가
메서드별로 제네릭 적용
Queue.java
Queue.java
ㄴ 문자열 타입을 받기 때문에 String 타입으로 명시