Backend

[RBF] 1주차

해로몬 2024. 10. 30. 18:09

 

 

  • 제네릭
  • Hash map/hash set
  • auto boxing/unboxing

1. 제네릭

제네릭의 장점 :

  • 제네릭을 사용하면 잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지
  • 클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하고 변환해줄 필요 없음 => 관리 용이
  • 비슷한 기능 지원 => 코드의 재사용성이 높아짐
타입 설명
<T> Type
<E> Element
<K> Key
<V> Value
<N> Number

 

 

[와일드 카드]

<?> :와일드 카드 = '알 수 없는 타입'

정해지지 않은 unknown 타입으로, 모든 타입을 대신할 수 있다.

<?>		// 모든 타입 가능. <? extends Object>랑 같은 의미

<K extends T>	// T와 T의 자손 타입만 가능 (K는 들어오는 타입으로 지정 됨)
<K super T>	// T와 T의 부모(조상) 타입만 가능 (K는 들어오는 타입으로 지정 됨)
 
<? extends T>	// T와 T의 자손 타입만 가능
<? super T>	// T와 T의 부모(조상) 타입만 가능
  • ? extends T : 상한 경계
  • ? super T : 하한 경계

*주의 : 경계가 지정되고 K는 특정 타입으로 지정이 되지만, ?는 타입이 지정되지 않는다는 의미다.

 

1)상한 경계  : <? extends T>

extends를 사용해서 와일드카드 타입의 최상위 타입을 정의함으로써 상한 경계를 설정함.

void printCollection(Collection<? extends MyParent> c) {
    // 컴파일 에러
    for (MyChild e : c) {
        System.out.println(e);
    }

    for (MyParent e : c) {
        System.out.println(e);
    }

    for (MyGrandParent e : c) {
        System.out.println(e);
    }

    for (Object e : c) {
        System.out.println(e);
    }
}
//<? extends MyParent>으로 가능한 타입은 MyParent와 미지(unknown)의 모든 MyParent 자식 클래스들이다.
//미지의 MyParent 자식 클래스라는 것은 자식이 어떤 타입인지 알 수 없다는 것

 

2) 하한 경계 : <? super T>

super를 사용해 와일드카드의 최하위 타입을 정의하여 하한 경계를 설정

void printCollection(Collection<? super MyParent> c) {
    // 불가능(컴파일 에러)
    for (MyChild e : c) {
        System.out.println(e);
    }

    // 불가능(컴파일 에러)
    for (MyParent e : c) {
        System.out.println(e);
    }

    // 불가능(컴파일 에러)
    for (MyGrandParent e : c) {
        System.out.println(e);
    }

    for (Object e : c) {
        System.out.println(e);
    }
}
//하위 타입인 경우에도 문제가 되는데, <? super MyParent>으로 가능한 타입은 MyParent와
//미지의 MyParent 부모 타입들이므로 MyChild와 같이 경계 아래의 하위 타입들은 당연히 추가될 수 없기 때문이다.

 

<참고>

https://mangkyu.tistory.com/241

https://st-lab.tistory.com/153

 

 

2. Hash map

map : key + value 두 쌍으로 데이터를 보관하는 자료 구조

키는 맵에 유일하게 있음. (value 중복 상관 x)

 

<HashTable과 HashMap차이점 >

HashTable HashMap
Thread 관점에서 안전한가? 안전하지 않은 대신 속도가 빠른가?

 

[사용법]

  • put : 저장
  • get : 읽기
  • containsKey : 이미 HashMap에 키가 있으면 값을 덮어 쓰지 않음
//키가 들어있는지 확인 -> 있으면 덮어쓰지 않음.
if(map.containsKey('key'){
	map.put('key',100);
    map.putIfAbsent('key',100);
}
  • containsValue : 값이 존재하는지 알아보는 메소드(true/false)
  • putAll : Map에 다른 Map을 전부 포함
public static void main(String[] org){
   Map<String,Integer> m1 = new HashMap();
   java.util.Map<String,Integer> m2 = new HashMap();
   
   m1.put("A", 100);
   m1.put("B", 200);

   m2.put("C", 300);
   m2.put("D", 400);
    //m2에 m1 전부 포함하기.
   m2.putAll(m1);
   System.out.println(m2);
}
//결과값
//putAll 대신 생성자 이용하여 데이터 넘기기.
Map<String,Integer> m2 = new HashMap(m1);
  • keySet : 키롤 set으로 넘겨주어 존재하는 키를 모두 순회함.
  • ForEach : 메소드 순회
  • equals : 같은 객체인지 판별
  • hashCode() : 각 개체가 갖는 유일한 값(Code)를 의미

Hash Set

[특징]

  • 중복된 값 허용X (자동으로 제거)
  • 순서 보장 X
  • null값 허용
  • 생성
  • 요소 값 추가
    • 입력되는 값이 내부에 존재하지 않는다면 값을 HashSet에 추가하고 true를 반환
    • 입력되는 값에 내부에 존재한다면 false 반환
  • size : HashSet 크기 구하기
  • 요소 값 삭제
    • remove(value) : value 값 제거
    • clear() : 모든 값 제거
  • HashSet 요소 값 검색
    • contains(valuse)
      • Hash 내부에 존재하는지 확인
  • 요소 값 출력
    • print : [Set의 전체값]이 출력
    • 반복자(iterator) : 전체 객체를 한번씩 반복해서 가져옴
HashSet<Integer> set = new HashSet<Integer>(Arrays.asList(1,3,5));

Iterator iter = set.iterator();	

//hasNext() : 가져올 객체가 있다면 true 리턴, 없다면 false 리턴
// next() : Iterator에서 하나의 객체를 가져올 수 있는 메소드
while(iter.hasNext()) {
    System.out.println(iter.next());
}

 

 

3.auto boxing / auto-unboxing

autoBoxing

  • primitive data에서 Wrapper Class로 자동으로 변환되는 것
  • 가벼운 데이터를 무거운 데이터에 넣기
  • 컴파일러가 Pirmitive에서 Object Data로 자동변환 함
  • Wrapper 클래스에 기본 자료형의 데이터 대입

primitive data

 

 

auto unboxing

  • Wrapper 클래스 -> primitivie type으로 자동 형변환 되는것
  • 컴파일러가 Object Data를 Primitive type으로 자동변환
  • 무거운 데이터를 가벼운 데이터에 넣기
  • 기본자료형에 wrapper 객체 대입

'Backend' 카테고리의 다른 글

MSA에 대해 알고가기  (0) 2025.02.13
AJAX(Asynchronous JavaScript and XML)  (0) 2024.11.29
[RBF] 2주차  (2) 2024.11.07