본문 바로가기
네이버클라우드/JAVA 웹 프로그래밍

JAVA 24일차 (2023-06-26) 자바 기초 DAY22_제네릭을 사용하여 타입을 파라미터로 다루기_개인프로젝트 - 마트 관리 시스템

by prometedor 2023. 6. 26.
## 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 타입으로 명시