728x90
Iterator<E>
- 클래스를 작성할 때, Object 타입 대신 T와 같은 타입 변수를 사용
//일반클래스
public interface Iterator{
boolean hasNext();
Object next();
void remove();
}
//제네릭 클래스
public interface Iterator<E>{
boolean hasNext();
E next();
void remove();
}
Iterator it = list.iterator();
while(it.hasNext()){
Student s = (Student)it.next(); //Object 클래스이므로 타입 불일치로 명시적 형변환을 해줘야함
}
//=>
Iterator<Student> it = list.iterator();
while(it.hasNext()){
Student s = it.next(); //Student 클래스 형이 일치
}
HashMap<K,V>
- 여러 개의 타입 변수가 필요한 경우 콤마(,)를 구분자로 선언
- K와 V의 타입은 다를 수 있음
public class HashMap<K,V> extends AbstractMap<K,V>{
(...생략...)
public V get(Object key){~~~}
public V put(K key, V value){~~~}
public V remove(Object key){~~~}
(...생략...)
}
//ex)
public class HashMap<K,V> extends AbstractMap<K,V>{
(...생략...)
public Student get(Object key){~~~}
public Student put(String key, Student value){~~~}
public Student remove(Object key){~~~}
(...생략...)
}
HashMap<String, Student> map = new HashMap<String, Student>(); //생성
map.put("홍길동", new Student("홍길동",1,1,100,100)); // 데이터 저장
package chapter12;
import java.util.ArrayList;
import java.util.Iterator;
class Student04Ex1{
String name = "";
int grade;
int no;
public Student04Ex1(String name, int grade, int no) {
this.name = name;
this.grade = grade;
this.no = no;
}
}
public class Study04Ex1 {
public static void main(String[] args) {
ArrayList<Student04Ex1> list = new ArrayList<Student04Ex1>();
list.add(new Student04Ex1("강아지", 1, 1));
list.add(new Student04Ex1("고양이", 1, 2));
list.add(new Student04Ex1("다람쥐", 2, 1));
Iterator<Student04Ex1> it = list.iterator();
while(it.hasNext()) {
// Student student = it.next(); //제네릭을 사용하면 형 변환이 필요하지 않음
// System.out.println(student.name);
//==
System.out.println(it.next().name); //형 변환을 하지 않으면 한 줄로도 작성 가능
}
System.out.println("================");
Iterator it2 = list.iterator();
while(it2.hasNext()) {
// Student student = it2.next(); //제네릭을 사용하지 않으면 형 변환 필요
// Student student = (Student)it2.next();
// System.out.println(student.name);
//==
System.out.println(((Student04Ex1)it2.next()).name);
}
}
}
package chapter12;
import java.util.HashMap;
class Student04Ex2{
String name = "";
int grade;
int no;
int kor;
int eng;
public Student04Ex2(String name, int grade, int no,int kor,int eng) {
this.name = name;
this.grade = grade;
this.no = no;
this.kor = kor;
this.eng = eng;
}
}
public class Study04Ex2 {
public static void main(String[] args) {
HashMap<String, Student04Ex2> map = new HashMap<>(); //생성자에 타입지정 생략 가능
map.put("홍길동", new Student04Ex2("홍길동", 1, 1, 100, 100));
//public V get(Object key) { //V => Student로 변경
Student04Ex2 s = map.get("홍길동");
System.out.println(map.get("홍길동").name);
}
}
제한된 제네릭 클래스
- extends로 대입할 수 있는 타입을 제한
class FruitBox<T extends Fruit>{ //Fruit 자손만 타입으로 지정가능
ArrayList<T> list = new ArrayList<T>();
(...생략...)
}
FruitBox<Apple> appleBox = new FruitBox<Apple>();
FruitBox<Toy> toyBox = new FruitBox<Toy>(); //Toy는 Fruit의 자손이 아니므로 에러
- 인터페이스의 경우 extends를 사용. 'implement'를 사용하지 않음!
interface Eatable{}
class FruitBox<T extends Eatable>{~~~}
제네릭의 제약
- 타입 변수에 대입은 인스턴스별로 다르게 가능
Box<Apple> appleBox = new Box<Apple>(); //Apple 객체만 저장가능
Box<Grape> grapeBox = new Box<Grape>(); //Grape 객체만 저장가능
static 멤버에 타입 변수 사용 불가. static 멤버는 모든 인스턴스에 공통
class Box<T>{
static T item; //에러
static int compare(T t1, T t2){~~~} //에러
...
}
배열, 객체 생성할 때 타입 변수 사용불가. 타입 변수로 배열 선언은 가능
new T => 객체 생성, 배열 생성 불가. new 예약어는 뒤에 오는 것이 타입이 확정되어 있어야함. T의 경우 타입 미정
class Box<T>{
T[] itemArr; // T타입의 배열을 위한 참조변수. 생성 가능
...
T[] toArray(){
T[] tmpArr = new T[itemArr.length]; //생성 불가
}
}
package chapter12;
import java.util.ArrayList;
interface Eatable05Ex1{
}
class Fruit05Ex1 implements Eatable05Ex1{
public String toString() {
return "Fruit";
}
}
class Apple05Ex1 extends Fruit05Ex1{
public String toString() {
return "Apple";
}
}
class Grape05Ex1 extends Fruit05Ex1{
public String toString() {
return "Grape";
}
}
class Toy05Ex1{
}
class Box05Ex1<T>{
ArrayList<T> list = new ArrayList<T>();
void add(T item) {
list.add(item);
}
T get(int i) {
return list.get(i);
}
int size() {
return list.size();
}
public String toString() {
return list.toString();
}
}
class FruitBox05Ex1<T extends Fruit05Ex1 & Eatable05Ex1> extends Box05Ex1<T>{
//,를 쓰지 않고 &를 사용
}
public class Study05Ex1 {
public static void main(String[] args) {
FruitBox05Ex1<Fruit05Ex1> fruitBox = new FruitBox05Ex1();
FruitBox05Ex1<Apple05Ex1> appleBox = new FruitBox05Ex1();
FruitBox05Ex1<Grape05Ex1> grapeBox = new FruitBox05Ex1();
// FruitBox05Ex1<Grape05Ex1> grapeBox1 = new FruitBox05Ex1<Apple05Ex1p>(); //타입 불일치
// FruitBox05Ex1<Toy05Ex1> toyBox = new FruitBox05Ex1(); // 에러
fruitBox.add(new Fruit05Ex1());
fruitBox.add(new Apple05Ex1());
fruitBox.add(new Grape05Ex1());
appleBox.add(new Apple05Ex1());
// appleBox.add(new Grape05Ex1()); //Grape는 Apple의 자손이 아니기 때문에 에러
System.out.println(fruitBox);
System.out.println(appleBox);
System.out.println(grapeBox);
}
}
728x90