25.02.27 (목) 14일차 Java -2

허배령·2025년 2월 27일

괴발개발 TIL

목록 보기
15/54

제네릭스 (Generics)

  • 클래스나 메서드 내부에서 다룰 데이터의 클래스 타입을 지정하거나,
    컬렉션이 다룰 클래스 타입을 제한하여 한 가지 종류의 클래스만 저장할 수 있게 한 기능
  • 클래스나 메서드가 사용할 타입을 지정(제한

제네릭스를 사용하는 이유

  • 컴파일 단계에서 '잘 못 된 타입을 사용할 수 있는 문제' 제거
  • 컬렉션에 저장된 여러 종류의 객체를 꺼내서 사용할 때,
    객체의 종류에 다라 매번 형변환을 해야하기 때문에 코드가 복잡해짐

제네릭스 이점

  • 컴파일 시 강한 타입 체크 가능(실행 시, 컴파일 시 에러 방지)
  • 타입 변환 제거 가능
List list = new ArrayList();
list.add(“hello”);					
String str = (String)list.get(0);

		↓↓↓↓

List<String> list = new ArrayList<String>();
list.add(“hello”);
String str = list.get(0);

제네릭스 타입과 표현식

  • 타입을 파라미터로 가지는 클래스와 인터페이스 선언 시 클래스 또는 인터페이스 이름 뒤에
    “< >” 부호를 붙이고 사이에는 타입 파라미터 위치
[표현식]	// 제네릭스는 객체만 허용, 기본자료형은 XX
클래스명<클래스타입> 레퍼런스 = new 생성자<클래스타입>();
클래스명<클래스타입> 레퍼런스 = new 생성자<>(); // JDK 1.7 부터 적용, 타입 추론
										  // 다이아몬드 연산자 (<>)

[사용예시]
ArrayList<Book> list1 = new ArrayList<Book>();
ArrayList<Book> list2 = new ArrayList<>();
Box<Integer> intBox = new Box<>();
> Java 7버전 이상에서는 우변타입 생략 가능
다이아몬드 연산자 : 컴파일러가 좌변(Box<Integer>)을 보고 우변의 타입 추론

Wrapper 클래스

  • 제네릭은 객체(Reference Type)만 허용
  • 제네릭은 기본자료형(Primitive Type)인 int, double, char같은 타입은 사용할 수 없다.
  • 대신 Wrapper 클래스를 사용
byte	-> Byte
short	-> Short
int		-> Integer
long	-> Long
float	-> Float
double	-> Double
char	-> Character
boolean	-> Boolean

int num = 10;
Integer num1 = num; // 오토박싱(Auto-boxing)
					// 기본형 -> 래퍼클래스 자동편환

int num2 = num1;	// 오토언박싱(Auto-unBoxing)
					// 래퍼클래스 -> 기본형
		
int number = Integer.parseInt("100"); // 문자열을 숫자로
        

제너릭스 예시

Box 클래스

// 제네릭 클래스 선언
public class Box<T> {
	// T는 타입 파라미터로, 
	// 실제 사용 시 구체적인 타입(String, Integer 등)으로 변환됨
	
	private T item; // T타입 변수 선언

	public T getItem() {
		return item;
	}

	public void setItem(T item) {
		this.item = item;
	}
}

public class box<T>{
    private T t;
    public void set(T t) {this.t = t;}
    public T get() {return t;}
}
		↓↓↓↓↓
        
Box<String> box = new Box<String>();
public class Box<String>{
    private String t;
    public void set(String t){this.t = t;}
    public String get(){return t;}
}

> 컴파일 시 타입 파라미터가 구체적인 클래스로 변경된다.        

Run 클래스

// String 타입으로 Box 객체 생성
		
		Box<String> stringBox = new Box<String>();
		// T가 String으로 대체 됨
		// -> 필드도 String 타입이 되고,
		//    getter/setter에서 사용되는 타입도 String
		
		stringBox.setItem("안녕 제네릭?");
		System.out.println(stringBox.getItem());
		
		intBox.setItem(123);
		System.out.println(intBox.getItem());
		

제네릭스가 설정된 레퍼런스를 인자로 넘기는 경우

ArrayList<Book> list = new ArrayList<Book>();
BookManager bm = new BookManager();
bm.printInformation(list);

//BookManager Class
public void printInformation(ArrayList<Book> list){.
}
> 메소드 쪽에서 받아주는 매개 변수도 제네릭스가 적용되어야 한다.

제네릭스가 설정된 레퍼런스를 리턴하는 경우

public ArrayList<Book> getInformation(){
	ArrayList<Book> list = new ArrayList<Book>();
	return list;
}
> 메소드의 반환형에도 제네릭스가 적용되어야 한다.

클래스에서 제네릭스 사용

class 클래스명<영문자> {
     영문자 레퍼런스;
}

* 영문자
   - 일반적으로 대문자 사용(ex. T, E, K, V)
   - 클래스 타입이 미정인 경우, 객체 생성 시 정해지는 클래스 타입을 
     영문자가 받아 영문자 사용 위치에 적용

멀티 타입 파라미터

public class Employee<D, P>{
    private D dept;
    private P person;

    public D getDept(){ return this.dept; }
    public P getPerson(){ return this.person; }

    public void setDept(D dept){ this.kind = kind; }
    public void setPerson(P person){ this.person = person; } 
}
Employee<Dept, Person> 
	= new Employee<Dept, Person>(); 

Employee<Dept, Person> 
	= new Employee<>();  // 타입 추론

> 제네릭스 타입은 두 개 이상의 타입 파라미터 사용 가능하며 각 타입 파라미터를 콤마로 구분

제네릭스 타입의 상속과 구현

public class ChildProduct<T, M> extends Product<T, M>{}
public class ChildProduct<T, M, C> extends Product<T, M>>{}

> 제네릭스 타입을 부모 클래스로 사용해야 할 경우 
타입 파라미터는 자식 클래스에도 기술 추가적인 타입 파라미터를 가질 수 있음

컬렉션

  • 자바의 컬렉션 : 자바에서 제공하는 자료구조 모음
    List, Set, Map
    여러데이터를 관리하기 위하여 사용 (배열보다 더 진화된 형태)

  • 자료를 구조적으로 처리하는 방법을 자료구조라고 일컫는데
    컬렉션은 자바에서 제공하는 자료구조를 담당하는 프레임워크(틀)

  • 추가, 삭제, 정렬 등의 기능처리가 간단하게 해결 되어 자료구조적 알고리즘을 구현할 필요 없음

자료구조

  • 데이터(자료)를 메모리에서 구조적으로 처리하는 방법론

배열의 문제점 & 컬렉션의 장점

배열의 문제점

  1. 한 번 크기를 지정하면 변경할 수 없다.

    • 공간 크기가 부족하면 에러가 발생 🡪 할당 시 넉넉한 크기로 할당하게 됨 (메모리 낭비)
    • 필요에 따라 공간을 늘리거나 줄일 수 없음
  2. 배열에 기록된 데이터에 대한 중간 위치의 추가, 삭제가 불편하다.

    • 추가, 삭제할 데이터부터 마지막 기록된 데이터까지 하나씩 뒤로 밀어내고 추가해야 함
      (복잡한 알고리즘)
  3. 한 타입의 데이터만 저장 가능하다.

컬렉션의 장점

  1. 저장하는 크기의 제약이 없다.

  2. 추가, 삭제, 정렬 등의 기능 처리가 간단하게 해결된다.

    • 자료를 구조적으로 처리 하는 자료구조가 내장되어 있어 알고리즘 구현이 필요 없음
  3. 여러 타입의 데이터가 저장 가능하다.

    • 객체만 저장할 수 있기 때문에 필요에 따라 기본 자료형을 저장해야 하는 경우
      Wrapper클래스 사용

컬렉션의 주요 인터페이스

  • Collection 인터페이스 : List, Set의 공통 코드를 작성해둔 부모 인터페이스
  • Java Collection : 자바의 자료구조 모음 (List, Set, Map)

    특징 중요!!!! 암기하면 좋음!

key와 value와 짝궁임 키밸류라고도 함
key를 보면 value의 값을 알 수 있음 (출석부느낌)
동명이인이 있어도 번호(key)로 구별할 수 있음
key의 값은 인데스번호가 아니라 값임!!!

List

  • 자료들을 순차적으로 나열한 자료구조로 인덱스로 관리되며, 중복해서 객체 저장 가능
    구현 클래스로 ArrayList, Vector, LinkedList가 있음

List 계열의 주요 메서드

add(E e), set(int index, E element), get(int index), size(), remove(int index) 주로 사용!!!

ArrayList

  • List의 후손으로 초기 저장 용량은 10으로 자동 설정되며 따로 지정도 가능
  • 저장 용량을 초과한 객체들이 들어오면 자동으로 늘어나며 고정도 가능
  • 동기화(Synchronized)를 제공하지 않음 => 검색(조회) 효율적
) List<E> list = new ArrayList<E>();

Vector

  • List의 후손
  • ArrayList와 동등하지만 동기화(Synchronized)를 제공한다는 점이 ArrayList와 차이점
    🡪 List 객체들 중에서 가장 성능이 좋지 않음

LinkedList

  • List의 후손으로, 인접 참조를 링크해 체인처럼 관리
  • 특정 인덱스에서 객체를 제거하거나 추가하게 되면 바로 앞/뒤 링크만 변경하면 되기 때문에
    객체 삭제와 삽입이 빈번하게 일어나는 곳에서는 ArrayList보다 성능이 좋음
  • 중간에 비어있는 인덱스가 없게하기 위해서 remove() 동작 시 뒤쪽 요소를 한칸씩 자동으로 당겨온다

Comparable, Comparator

public int compareTo(Student other) {
		// compareTo() : 두 객체를 비교하고 순서를 결정
		// 반환값 : 0(같음), 양수(왼쪽 객체가 큼), 음수(왼쪽 객체가 작음)
		
		// 현재객체의 나이 - 다른객체의 나이
		// -> 값이 양수면 현재객체의 나이가 더 크다
		// -> 값이 음수면 현재객체의 나이가 더 적다
		return this.age - other.age; // 나이를 기준으로 오름차순 정렬 (작 -> 큰)
		// return other.age - this.age; // 나이를 기준으로 내림차순 정렬 (큰 -> 작)
	}

Comparable
studentList - 총 5명의 학생 (나이 다름)
-> 나이 오름차순으로 정렬
-> Student implements Comparable

Collections.sort()

profile
인생은 변수

0개의 댓글