Java) Java 복습(3) 제네릭 프로그래밍

Jay Kim·2022년 1월 12일
0

Java

목록 보기
3/9
ArrayList list = new ArrayList();//타입 미설정 Object로 선언된다.
ArrayList<Student> members = new ArrayList<Student>();//타입설정 Student객체만 사용가능
ArrayList<Integer> num2 = new ArrayList<>();//new에서 타입 파라미터 생략가능
ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(1,2,3));//생성시 값추가

1.제네릭 프로그래밍 -> 컬렉션 프레임워크에서 많이 사용

-변수의 선언이나 메서드의 매개변수를 하나의 참조 자료형이 아니라 여러 자료형으로 변환할 수 있도록 프로그래밍

-클래스 정의 시 , 구체적인 타입 명시 x, 변수 형태로 작성

-> 클래스를 선언하여 객체를 생성 할 때, 구체적인 타입을 기재 

-제네릭 클래스 : 타입을 변수로 표시 (타입 매개변수) , 타입 매개변수는 객체 생성 시에 프로그래머에 의해 결정됨

ex) Box<String> strBox = new Box<String>(); //String타입만 저장함.

-제네릭 객체 생성 : 제네릭클래스 <적용할 타입> 변수 = new 제네릭 클래스<적용할 타입>();

-타입 매개변수

-하나의 대문자로 이름 설정
-클래스 안에 여러 개의 타입 매개변수 존재 가능 but 타입의 이름은 클래스나 인터페이스 안에서 유일해야 함

-종류: E-Element / K-Key / N-Number / T -Type / V -Value / S,U,V 등 ( static 키워드는 T에 쓸 수 없다)
-<> : 다이아몬드 클래스의 생성자 호출 시, 타입 인수를 명시 x , 컴파일러가 타입 추측
-ex) Box strBox = new Box< >();

interface Pair<K, V> {
	public K getKey();
	public V getValue();
}

public class OrderedPair<K, V> implements Pair<K, V> {
	private K key;
	private V value;

	public OrderedPair(K key, V value) {
		this.key = key;
		this.value = value;
	}

	public K getKey() { 
		return key; 
	}
	
	public V getValue() { 
		return value; 
	}
}
public class PairTest {
	public static void main(String[] args) {
		Pair<String, Integer> pair1 = new OrderedPair<String, Integer>(Even, 8);
		Pair<String, String> pair2 = new OrderedPair<String, String>(Hi, “nice~);
		 
		pair1과 pair2는 인터페이서 Pair 참조 변수로 선언되었다.
		new OrderPair<String, Integer>KString으로 실체화하고, VInteger로 실체화한다.
		오토박싱(autoboxing)에 의하여 int(위의 값 8)Integer 객체로 자동 변환된다.
		오토박싱이란 기초 자료형을 대응되는 클래스 객체로 자동 변환해주는 기능이다.
		
		또는 아래와 같은 방식도 가능하다.
		
		Pair<String, Integer> pair1 = new OrderedPair<>(Even, 8);
		Pair<String, String> pair2 = new OrderedPair<>(Hi, “nice~);
	}
}

-제네릭 메소드

-일반 클래스의 메소드에서도 타입 매개변수 이용해 제네릭 메소드 정의 가능
-제네릭 메소드에서의 타입 매개변수의 범위는 메소드 내부로 제한
-한정된 타입 매개변수 : 타입 매개변수로 전달되는 타입의 종류를 제한하기 위해 extends 키워드 사용
-형태) <타입 매개변수> 반환타입 메서드 이름(...) {}

  public static <T extends Comparable> T getMax(T[] a){   }
TcompareTo()라고 하는 Comparable 인터페이스를 구현해야 함 
따라서 클래스의 범위를 Comparable 인터페이스를 구현한 클래스로 제한
-> 타입T가 comparable 인터페이스를 구현한 클래스들에 대해서만 호출 가능

-타입 매개변수 상속 관계
-ex)number를 타입 매개변수로 객체 생성 ->number의 자식 클래스인 Integer, Dobule, Float 객체도 처리 가능
-타입 매개변수에서 상속관계가 성립하는 것과 어떤 타입 매개변수를 가진 제네릭 클래스에서 상속관계가 성립하는 것은 서로 다르다는 것이다.
-와일드 카드 :? 어떤 타입이던지 표현 가능
-모든 타입에 매치되는 리스트를 매개변수로 받을 수 있는 코드 List<?>


2.컬렉션 프레임워크 : 프로그램 구현에 필요한 자료구조를 구현해 놓은 라이브러리

  • Collection 인터페이스 : 하나의 객체를 관리하기 위한 메소드가 선언된 인터페이스
    1)LIST 인터페이스) 객체의 번지 참조 , 순서가 있고, 중복 허용(동일한 번지 참조) , null 삽입 가능
    -ArrayList, Vector, LinkedList, Stack Queue ->배열 기능 구현
    2)SET 인터페이스) 순서가 없고, 중복 허용 않음 , get메소드 지원 않음 HashSet, TressSet
메소드의미
boolean add(E e)collection에 객체 맨 끝에 추가
void add(int index, E element)주어진 인덱스에 객체 추가
set(int index, E element)주어진 인덱스에 저장된 객체를 주어진 객체로 바꿈
void clear()모든 객체를 제거
Iterator iterator순환할 반복자(iterator)를 반환
boolean remove(Object o)매개변수에 해당하는 인스턴스 존재하면 제거
int size()요소의 개수를 반환
isEmpty()컬렉션이 비어있는지 여부 확인
indexOf(value)value값이 있는 index 반환 없으면 -1

1)ArrayList : List 인터페이스를 상속 받은 클래스 , 가변적 크기

ArrayList list = new ArrayList();//타입 미설정 Object로 선언된다.
ArrayList<Student> members = new ArrayList<Student>();//타입설정 Student객체만 사용가능
ArrayList<Integer> num2 = new ArrayList<>();//new에서 타입 파라미터 생략가능
ArrayList<Integer> list2 = new ArrayList<Integer>(Arrays.asList(1,2,3));//생성시 값추가

2)LinkedList : ArrayList와 선언 방식 같지만 초기 크기 설정 X

LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(1,2,3,4,5));
list.addFirst(1);//가장 앞에 데이터 추가
list.addLast(2);//가장 뒤에 데이터 추가
list.removeFirst(); //가장 앞의 데이터 제거
list.removeLast(); //가장 뒤의 데이터 제거

3)Vector :ArrayList와 동일 내부구조이지만, 동기화된 메소드로 구성되어 멀티 스레드가 동시에 메소드들 실행 불가, 하나의 스레드가 실행을 완료해야 다른 스레드 실행 가능 -> 멀티스레드 환경 good
-Vector를 사용할때에는 타입을 명시해주는 것이 좋음

Vector v = new Vector();//타입 미설정 Object로 선언된다.
Vector<Student> student = new Vector<Student>(); //타입설정 Student객체만 사용가능
Vector<Integer> num2 = new Vector<Integer>(); //타입설정 int타입만 사용가능
Vector<Integer> num3 = new Vector<>(); //new에서 타입 파라미터 생략가능
Vector<String> v2 = new Vector<String>(10);//초기 용량(capacity)지정
Vector<Integer> v3 = new Vector<Integer>(Arrays.asList(1,2,3)); //초기값 지정
-모든 값 제거 시 clear() 메소드 or removeAllElements()
-vector 자료 개수 : size() // 물리적 크기 : capacity() 메소드 사용

4)HashMap : get메소드 지원 X, 자동정렬X, 중복 X

-중복 저장 X : hashCode() 메소드 호출해서 해시 코드 얻은 후 저장되어 있는 객체들의 해시코드와 비교 -> 해시코드가 같으면 equals() 메소드로 두 객체 비교 -> true면 동일 객체이므로 중복 저장 X ( 문자열 경우 , 같은 문자열이면 동일한 String객체로 간주)
-저장공간 : 객체 추가 시 한 칸씩 늘리지 않고 저장용량을 약 두배로 늘림

HashSet<Integer> set1 = new HashSet<Integer>();//HashSet생성
HashSet<Integer> set2 = new HashSet<>();//new에서 타입 파라미터 생략가능
HashSet<Integer> set3 = new HashSet<Integer>(set1);//set1의 모든 값을 가진 HashSet생성
HashSet<Integer> set4 = new HashSet<Integer>(10);//초기 용량(capacity)지정
HashSet<Integer> set5 = new HashSet<Integer>(10, 0.7f);//초기 capacity,load factor지정
HashSet<Integer> set6 = new HashSet<Integer>(Arrays.asList(1,2,3));//초기값 지정

-HashSet 값 출력 :System.out.println(set); //전체출력 [1,2,3] 대괄호로 묶어서 전체 값 출력
-> 인덱스로 객체를 가져오는 get(index) 메소드가 없음 ->전체 객체를 대상으로 한 번씩 반복해서 가져오는 반복자(Iterator) 사용!!

Iterator iter = set.iterator();	// Iterator 사용
while(iter.hasNext()) {//값이 있으면 true 없으면 false
    System.out.println(iter.next());	//하나의 객체 가져올 때 next() 메소드 사용
}

5)TreeSet ) HashSet과는 달리 TreeSet은 이진 탐색 트리(BinarySearchTree) 구조 ->추가/삭제는 시간이 더 걸리지만 정렬/검색 성능 good , 선언 시 크기 지정 X

TreeSet<Integer> set1 = new TreeSet<Integer>();//TreeSet생성
TreeSet<Integer> set2 = new TreeSet<>();//new에서 타입 파라미터 생략가능
TreeSet<Integer> set3 = new TreeSet<Integer>(set1);//set1의 모든 값을 가진 TreeSet생성
TreeSet<Integer> set4 = new TreeSet<Integer>(Arrays.asList(1,2,3));//초기값 지정
메소드의미
set.first()최소값
set.last()최댓값
set.higher(value)value입력값보다 큰 데이터 중 최소값
set.lower(Value)value입력값보다 작은 데이터 중 최댓값

2.Map 인터페이스

->Map : 키와 값으로 구성된 Entry객체를 저장하는 구조를 가지고 있는 자료구조

-키와 값 모두 객체 / 키는 중복 X(동일 키 저장 시 기존 값 없어지고 새로운 값으로 대치), 값은 중복 O
-HashMap

HashMap<String,String> map1 = new HashMap<String,String>();//HashMap생성
HashMap<String,String> map2 = new HashMap<>();//new에서 타입 파라미터 생략가능
HashMap<String,String> map3 = new HashMap<>(map1);//map1의 모든 값을 가진 HashMap생성
HashMap<String,String> map4 = new HashMap<>(10);//초기 용량(capacity)지정
HashMap<String,String> map5 = new HashMap<>(10, 0.7f);//초기 capacity,load factor지정
HashMap<String,String> map6 = new HashMap<String,String>(){{//초기값 지정
    put("a","b");
}};
메소드의미
map.put(key, "value")값 추가
map.remove(key)키값에 제거
map.clear()모든 값 제거
map.get(key)key값의 value 얻기
entrySet() or keySet() 활용하여 객체 반환받은 후 출력전체를 출력

-entrySet() 활용 : key와 value 모두 필요한 경우 사용
-KeySet() 활용 : key값만 필요한 경우
-Iterator 사용 : 반복문 대신 (Iterator는 자바의 컬렉션 프레임워크에서 컬렉션에 저장되어 있는 요소들을 읽어오는 방법/삭제)
-> Iterator<데이터타입> iterator명(it) = 컬렉션.iterator();

Iterator 메소드의미
Iterator.hasNext()Iterator 안에 다음 값이 들어있으면 true
Iterator.next()다음 값 가져오기
Iterator.remove()next() 시에 가져왔던 값을 컬렉션에서 삭제

*반드시 next() 후에 사용해야 함

//entrySet() 활용
for (Entry<Integer, String> entry : map.entrySet()) {
    System.out.println("[Key]:" + entry.getKey() + " [Value]:" + entry.getValue());
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도

//KeySet() 활용
for(Integer i : map.keySet()){ //저장된 key값 확인
    System.out.println("[Key]:" + i + " [Value]:" + map.get(i));
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도

___________________________________________________________________
HashMap<Integer,String> map = new HashMap<Integer,String>(){{//초기값 지정
    put(1,"사과");
    put(2,"바나나");
    put(3,"포도");
}};
		
//entrySet().iterator()
Iterator<Entry<Integer, String>> entries = map.entrySet().iterator();
while(entries.hasNext()){
    Map.Entry<Integer, String> entry = entries.next();
    System.out.println("[Key]:" + entry.getKey() + " [Value]:" +  entry.getValue());
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도
		
//keySet().iterator()
Iterator<Integer> keys = map.keySet().iterator();
while(keys.hasNext()){
    int key = keys.next();
    System.out.println("[Key]:" + key + " [Value]:" +  map.get(key));
}
//[Key]:1 [Value]:사과
//[Key]:2 [Value]:바나나
//[Key]:3 [Value]:포도

1)TreeMap :객체를 저장하면 자동으로 정렬되는데, 키는 저장과 동시에 자동 오름차순으로 정렬되고 숫자 타입일 경우에는 값으로, 문자열 타입일 경우에는 유니코드로 정렬
-HashMap과 달리 Tree구조임으로 항상 정렬되어 있음 -> 최솟값, 최댓값 바로 가져올 수 있음

0개의 댓글