본문 바로가기
Backend boot camp/Session1

[JAVA] 컬렉션(Collection)

by orioncsy 2022. 9. 6.

0. 제네릭(Generic)

개요

  • 인스턴스 변수에 다른 타입의 변수를 저장하려면 각기 다른 클래스를 저장
  • 이러한 불편함을 해소하는 것이 제네릭

학습 목표

  • 제네릭 장점
  • 제네릭 클래스를 정의 활용
  • 제네릭 메서드 정의 활용

제네릭(Generic)이란?

  • class Example
    • 클래스명 뒤에 라는 타입을 적어서 T를 활용
  • 가 들어가면 T에 해당하는 부분을 int로 변환
    • Integer는 wrapper class, int는 primitive class
    • primitive는 기본 자료형이고 wrapper는 매개변수로 객체를 필요로 할 때 사용
    • Character, Integer 제외하고 첫 문자만 대문자로 표현
  • 타입을 구체적으로 지정하는 것이 아니라 일반화해두는 것
    • 클래스와 메서드에 사용 가능

제네릭 클래스

  • 제네릭 클래스
    • 제네릭이 사용된 클래스
    • class Example{…}
    • T를 타입 매개변수
    • 여러 개 지정 가능 : class Example <T, K, V>
    • T(Type), K(Key), V(Value, E(Element), N(Number), R(Result)

제네릭 클래스를 정의할 때 주의할 점

  • 클래스 변수에는 타입 매개변수 사용 불가
    • 다른 타입으로 선언되는 경우 같은 변수로 공유가 불가능하기 때문

제네릭 클래스 사용

  • wrapper 클래스를 사용
    • Exmample example = new Example();
    • Exmample example = new Example<>();
  • 제네릭 클래스에 다형성 적용 가능
  • class Vehicle{ ... }; class Car extends Vehicle{ ...}; class Food{ ... }; class Garage{ private item; public T getItem(){ return item; } public T setItem(T item){ this.item=item; } public static void main(String args[]){ Garage garage = new Garage<>(); garage.setItem(new Car()); // 다형성(polymorphism) garage.setItem(new Food()); //error

제한된 제네릭 클래스

  • 타입 매개변수를 선언할 때 특정 클래스 하위 클래스로 지정할 수 있다
  • 인터페이스도 가능하다.(선언할 때 똑같이 extends로 사용)
  • 특정 클래스와 인터페이스를 동시 적용할 때 extends A & B로 적용
class Vehicle{ ... };
class Car implements Vehicle{ ...};
class SportsCar extends Car implements Vehicle{ ... };
class Garage<T extends Vehicle & Car>{
    private <T> item;
    public T getItem(){
        return item;
    }
    public T setItem(T item){
        this.item=item;
}

public static void main(String args[]){
    Garage<Vehicle> garage = new Garage<>();
    garage.setItem(new SportsCar()); // 다형성(polymorphism)
    garage.setItem(new Car());

제네릭 메서드

  • 특정 메서드만 제네릭으로 선언 가능
  • 반환 타입 앞에 타입 매개변수 선언으로 사용
    • public void full(T amount){ … }
  • 클래스 타입 매개변수와 별개
    • 같은 T를 사용해도 클래스 제네릭은 클래스가 인스턴스화 될 때, 제네릭 메서드는 메서드 호출될 때 지정
    • 메서드 타입 매개변수
      • Car.full(50);
      • Car.full(50);//생략 가능
  • 제네릭 메서드는 메서드를 사용할 때 지정되기 때문에 String 메서드인 length() 같은 것 사용 불가
  • 최상위 메서드인 Object 메서드는 사용 가능

와일드카드

  • 어떠한 타입으로도 대체 가능한 타입 파라미터
    • <? extends T> : T와 T의 하위 클래스를 파라미터로 받기
    • <? super T> : T와 T의 상위 클래스를 파라미터로 받기
    • <?> : <? extends Object>와 동일, 모든 타입 가능

1. 예외 처리(Exception Handling)

개요

학습 목표

  • 예외 처리란
  • 컴파일 에러 VS 런타임 에러
  • 예외 클래스의 상속 계층
  • try-catch문
  • throws VS throw

예외 처리란?

예외 처리

  • 목적 : 프로그램의 비정상적 종료 방지, 정상 실행 상태 유지
  • 에러 발생 원인
    • 외부 요인
      • 네트워크 문제
      • 메모리 부족
    • 내부 요인
      • 입력 오류
      • 코드 에러
      • 유효하지 않은 파일
  • 예제
import java.io.*;

public class Main{
    public static void main(String[] args) {
        BufferedReader reader = new BufferedReader(new FileReader("not"));
                // 존재하지 않은 파일 호출
                //빨간 줄로 나옴
                //FileNotFoundException
        System.out.println(reader.read());
        reader.close();

                int arr[]={1,2,3,4,5,6};
        System.out.println(arr[7]);
                //ArrayIndexOutOfBoundsException: Index 7
    }
}

컴파일 에러 VS 런타임 에러

컴파일 에러

  • 컴파일 에러 : 컴파일할 때 발생하는 에러
    • Syntax error : 문법적인 오류
    • 자바 컴파일러가 감지 및 공지

런타임 에러

  • 런타임 에러 : 코드를 실행할 때 발생하는 에러
    • 컴퓨터가 수행할 수 없는 작업 요청할 때 발생
    • JVM(자바 가상 머신)으로 감지

에러와 예외

  • 에러 : 한번 실행하면 복구하기 어려운 수준의 오류( 스택오버플로우, 메모리 부족)
  • 예외 : 상대적으로 수습 가능한

예외 클래스 상속 계층

예외 클래스 계층

  • java.lang → Object → Throwable → Error /Exceptions

일반 예외 클래스

  • RuntimeException 클래스 및 하위 클래스를 제외한 Exception 클래스
  • 컴파일러가 확인한다고 하여 checked exception이라 부름
  • 사용자 편의 실수로 주로 발생
  • ClassNotFoundException, DataFormatException

실행 예외 클래스

  • 실행 시 발생하는 RuntimeException
  • 컴파일러가 예외 처리 코드 검사를 하지 않아 unchecked exception이라 부름
  • ClassCastException, ArrayIndexOutOfBoundsException, NullPointerException

try - catch 문

  • try{…}
    • 예외가 발생할 수 있는 코드
  • catch(Exception e){…}
    • 해당 예외가 발생할 경우 처리할 코드
    • Exception 클래스는 모든 클래스를 받는다
    • 여러 catch문을 작성하여 해당 예외에 대한 처리 가능
  • finally{…}
    • 예외와 상관없이 실행
  • 예제
public class Main{
    public static void main(String[] args) {
        System.out.println("start program");
        try{
            printlen(null);
        }
        catch(ArrayIndexOutOfBoundsException e){
            System.out.println("ArrayIndexOutOfBoundsException");
        }
        catch(NullPointerException e){
            System.out.println(e.getMessage()); // null 출력
            System.out.println(e.toString()); // java.lang.NullPointerException 출력
            e.printStackTrace();
                        //java.lang.NullPointerException
                        //at Main.printlen(Main.java:21)
                        //at Main.main(Main.java:6) 출력
        }
        finally{
            System.out.println("end program");
        }
    }
    static void printlen(String str){
        System.out.println("strlen = " + str.length());
    }
}
  • 에러 정보
    • .getMessage() : 에러 원인 간단히 출력
    • .toString() : 에러 내용과 원인 출력
    • .printStackTrace() : 에러 발생 근원지에서 단계별로 에러 출력

에러 전가

throws()

  • 메서드 내에 발생할 수 있는 예외를 상위(호출하는 쪽)에 전가하는 것
  • main 메서드 뒤에 선언이 가능하고 이 경우 JVM이 콘솔에 출력하여 처리
  • 선언
    • void method() throws Exception { … }

throw

  • 예외를 의도적으로 발생
  • 사용 : throw Exception
  • 예제
public class Main{
    public static void main(String[] args) {
        try{
            printlen(null);
        }
        catch(NullPointerException e){
            System.out.println(e.toString());
        }
    }
    static void printlen throws NullPointerException(String str){
        try {
            System.out.println("strlen = " + str.length());
        }
        catch (NullPointerException e){
            throw e; // 예외 강제 발생
        }
    }
}

2. 컬렉션 프레임워크(Collection Framework)

개요

  • 학습 목표
    • 컬렉션 프레임워크의 핵심 인터페이스 이해
    • 주요 인터페이스, 컬렉션 클래스의 메서드 사용
    • 상황에 적합한 인터페이스와 컬렉션 클래스 판단

컬렉션 프레임워크란?

  • 컬렉션 프레임워크
    • 컬렉션 : 여러 데이터들의 집합
    • 컬렉션 프레임워크 : 컬렉션을 다루기 위한 메서드 집합
  • 특정 자료구조에 데이터 추가, 삭제, 수정, 검색에 대한 메서드 제공

컬렉션 프레임워크의 구조

출처 :&nbsp;https://hyuntaekhong.github.io/blog/java-basic25/

  • 컬렉션 프레임워크의 주요 인터페이스
    • List : 데이터 순서 유지, 중복 저장 가능
      • ArrayList, Vector, Stack, LinkedList
    • Set : 데이터 순서 유지 안됨, 중복 저장 불가
      • HashSet, TreeSet
    • Map : key와 value 쌍으로 데이터 저장
      • HashMap, HashTable, TreeMap, Properties
  • List와 Set은 공통점이 많아 Collection이라는 인터페이스에 묶인다

Collection 인터페이스

출처 :&nbsp;https://www.crocus.co.kr/1553

List

  • List
    • 배열과 같이 객체를 일렬로 놓은 구조
    • 객체를 저장하면 자동으로 인덱스 부여
    • 인덱스를 활용하여 객체 추가, 검색, 삭제 가능
  • List 인터페이스의 공통 메서드

출처 :&nbsp;https://palpit.tistory.com/entry/Java-%EC%BB%AC%EB%A0%89%EC%85%98-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC-List

ArrayList

  • List 인터페이스로 구현
    • 연속적으로 데이터 저장
    • Vector와 유사하지만 개선됨
    • 객체를 추가하면 자동으로 용량 늘어남
List<Integer> num1 =new ArrayList<Integer>();
//초기 용량은 10
List<Integer> num2 =new ArrayList<Integer>(30);
//저장 용량 30으로 설정
  • 객체를 삭제하게 되면 해당 객체 이후를 1씩 당긴다
  • 빈번한 삽입과 삭제의 경우 LinkedList가 효율적

LinkedList

  • List 인터페이스로 구현
    • 불연속적으로 데이터 저장
    • 서로 연결됨
  • node에 값이 있고 이전 객체 주소 값, 이후 객체 주소 값이 존재
  • 삭제할 때 이전 객체의 연결을 변경(ArrayList보다 효율적)

ArrayList와 LinkedList 차이

  • ArrayList
    • 중간에 존재하는 객체 추가 및 삭제할 경우 데이터 이동이 크게 일어남
    • 특정 인덱스의 객체 주소 값을 찾는 검색에서는 유리
  • LinkedList
    • 중간에 존재하는 객체 추가 및 삭제할 경우 주소 값만 변경한다
    • 특정 인덱스의 객체 주소 값을 찾으려면 순차적으로 접근해야 해서 불리

Iterator

Iterator

  • 컬렉션에 저장되어 있는 요소를 순차적으로 읽는 것
  • Collection 인터페이스에, iterator 인스턴스를 반환하도록 구현한 iterator() 메서드로 활용
  • List, Set은 Collection 인터페이스에서 구현하였기 때문에 사용 가능
  • 사용 메서드

출처 : UrClass

  • 활용
List<Integer> list=new ArrayList();
Iterator<Integer> iterator = list.iterator();
While(iterator.hasNext()){
    int num=iterator.next();
    iterator.remove(); // next로 가져온 객체 삭제
}

Set

Set

  • 중복된 값 허용하지 않고 저장 순서가 상관없는 컬렉션 클래스
  • Set 공통 메서드

출처 :&nbsp;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=qkrghdud0&logNo=220699616483

HashSet

  • Set 인터페이스를 구현한 컬렉션 클래스
  • 중복 값 허용하지 않고, 순서 상관없다
    • hashCode() 메서드를 사용해 해쉬 코드를 가져오고
    • 기존에 있는 객체와 같으면 add()에 false 반환
    • 기존에 있는 객체와 다르면 add()에 true 반환 후 추가
  • 활용
HashSet<Integer> nums=new HashSet<Integer>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(1); // 중복
Iterator it=nums.iterator();
while(it.hasNext()){
    System.out.println(it.next()); //1,2,3,4 출력
}

TreeSet

  • 중복 저장 허용하지 않고, 저장 순서 무관
  • 이진 탐색 트리(Binary search tree) 형태
    • 하나의 부모 노드에 최대 두 개의 자식 노드로 이루어진 이진트리의 일종
    • 왼쪽 노드에는 부모 노드보다 같거나 작은 값, 오른쪽 노드에는 같거나 큰 값
    • 최상단의 노드가 root 노드
TreeSet<Integer> nums = new TreeSet<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(1);
System.out.println(nums); // 오름차순으로 출력
System.out.println(nums.higher(3)); //3보다 큰 가장 작은 수 4 출력 
System.out.println(nums.first()); // 최솟값 출력
System.out.println(nums.last());//최댓값 출력
System.out.println(nums.subset(1,3); //1-3까지 수 출력

Map<key, value>

Map

  • 키와 값으로 구성된 객체를 저장하는 구조
  • 객체를 Entry 객체라고 부른다
  • key, value 모두 객체로 저장
  • key는 중복되지 못하지만 value는 중복 가능
  • Map 인터페이스 공통 메서드

출처 :&nbsp;https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=heartflow89&logNo=221002846073

HashMap

  • 키와 값으로 저장 위치 결정
    • 삽입 순서, 위치 무관
  • 해싱 사용
    • 많은 양의 데이터 효율적으로 처리
  • 활용
import java.util.*;

class HashMap{
    public static void main(String[] args){
        HashMap<String, Integer> hmap=new HashMap<>();
        map.put("banana", 1200);
        map.put("apple", 1500);
        map.put("pineapple", 5000);
        map.put("melon", 9000);
        map.remove("melon");
        System.out.println("entry 수: ", hmap.size());
        System.out.println("banana price : ", hmap.get("banana"));

        Set<String> keySet = hmap.keySet();
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key=it.next();
            System.out.println(key + " " + hmap.get(key)); // 키와 값을 모두 출력
        }
        Set<Map.Entry<String, Integer>> entrySet =hmap.entrySet();
        Iterator<Map.Entry<String, Integer>> it2=entrySet.iterator();
        while(it2.hasNext()){
            System.out.println(it2.getKey() + " " +it2.getValue());
        }
    }
}

HashTable

  • HashMap의 이전 버전
    • HashMap과 구조가 동일하고 사용 방법 유사

컬렉션 클래스의 정리

  • 키, 값 쌍?
    • yes - 순서가 중요하지 않으면 HashMap, 중요하면 LinkedHashMap, 정렬이 필요하면 TreeMap
    • No
      • 객체 중복 허용 X : 순서가 중요하지 않으면 HashSet, 중요하면 LinkedHashSet, 정렬이 필요하면 TreeSet
      • 객체중복 허용
        • 첫 요소나 마지막 요소 접근? 리스트의 크기가 큰가? 객체를 빈번히 삭제/수정하나? ->LinkedList
        • 그렇지 않은 경우 -> ArrayList

'Backend boot camp > Session1' 카테고리의 다른 글

[JAVA] 심화 - Thread, JVM  (1) 2022.09.19
[JAVA] 심화(Effective)  (0) 2022.09.14
[JAVA] 객체 지향 프로그래밍 심화  (0) 2022.09.06
[JAVA] 객체 지향 프로그래밍 기초  (0) 2022.09.06
[JAVA] 기초 - 배열  (0) 2022.09.06