자바 기초

열거형과 컬렉션 프레임워크

YJH3968 2021. 4. 18. 20:51
728x90

1. 열거형

  • 열거형(Enum) : 미리 정의된 상수들의 집합을 만들기 위해 사용하는 자바의 참조형
  • 열거형의 선언은 다음과 같이 한다.
접근제한자 enum 열거형이름 implements 인터페이스들 {
    열거형데이터들(내부생성자매개변수들) { method정의 }, ... ;
    내부멤버필드들;
    내부생성자method들() { ... }
    내부멤버method들_getters&setters
    출력을 위한 toString() method의 오버라이딩
    그외필요한method들
}
  • 독립적인 열거형의 접근 제한자는 public과 package만 사용할 수 있다. 열거형을 클래스 내에 선언할 때는 접근 제한자를 모두 사용할 수 있다.
  • 클래스를 선언할 때 'class 클래스이름'과 같이 class 예약어를 사용하듯이 열거형을 선언할 때는 'enum 열거형이름'처럼 enum이라는 예약어를 사용한다.
  • 열거형은 외부에서 생성자 method를 사용해 객체를 생성하지 못하므로 클래스를 상속받지는 못한다. 하지만 method 선언은 가능해 인터페이스는 구현할 수 있다.
  • 기본적으로 Comparable(데이터 비교 인터페이스), Serializable(전송에 관련된 직렬화 인터페이스)는 구현되어 있기 때문에 따로 구현할 필요는 없다.
  • 열거형은 참조형이기 때문에 Object 클래스에 구현되어 있는 equals(), toString(), getClass() 등의 기본 method를 사용할 수 있다.
  • 형식에서 두 번째 줄이 열거형에서 실제로 제공되는 상수 필드들이다.
// 열거형에서 상수 필드 정의 예시
SUNDAY, MONDAY(1), TUESDAY(2, "화"), ... ;
  • 이렇게 선언한 열거형은 모두 자동으로 public static final로 처리되고 내부 toString() method에서 각 필드의 이름을 출력하도록 지원한다.
  • 또한 열거형은 상수 필드이고 Comparable 인터페이스가 구현되어 있기 때문에 '=='이나 compareTo()와 같은 연산자나 method를 사용할 수 있다.
  • 상수 필드를 선언할 때 method를 각 상수 필드의 내용부에 정의할 수도 있다. 이러한 경우 모든 상수 필드로 하여금 해당 method를 구현하도록 하기 위해 일반적으로 인터페이스를 사용한다.
interface MyPosition {
    public String myDay();
}
enum MyDay implements MyPosition {
    SUNDAY {
        public String myDay() {
            return "[일] 월 화 수 목 금 토";
        }
    },
    MONDAY {
        public String myDay() {
            return "일 [월] 화 수 목 금 토";
        }
    };
}

// 이렇게 선언될 경우 myDay() method를 사용할 수 있다.
public static void main(String[] ar) {
    System.out.println(MyDay.MONDAY.myDay());
}
  • 이제 상수 필드를 정의하는 부분 외의 나머지 부분의 역할을 살펴본다. 구체적인 예시로 요일을 다루는 열거형을 작성하면 다음과 같다.
enum EnumDay {
    SUNDAY, MONDAY(1), TUESDAY(2, "화요일");
    // 내부 멤버 필드들
    private int position; 
    private String dayString;
    // 내부 생성자 method들
    EnumDay() { // 내부 생성자 method에는 접근 제한자를 사용할 수 없다.
        position = 0;
        dayString = "일요일";
    }
    EnumDay(int pos) {
        this.position = pos;
        this.dayString = "월요일"
    }
    EnumDay(int pos, String dayStr) {
        this(pos);
        this.dayString = dayStr;
    }
    // 내부 멤버 method들_getters&setters
    public int getPosition() {
        return position;
    }
    public String getDayString() {
        return dayString;
    }
}
  • 기본적으로 열거형을 코드로 작성하면 선언한 상수 필드 이름이 출력되도록 toString() method가 자동으로 만들어지지만 toString() method를 오버라이딩해 필요에 따라 자신이 원하는 형태로 출력할 수 있다.
public enum EnumDay {
    SUNDAY("일"), MONDAY("월");
    private String dayString;
    EnumDay(String dayStr) {
        this.dayString = dayStr;
    }
    public String toString() {
        return dayString + "요일";
    }
}

 

2. 컬렉션 프레임워크의 개요와 특징

  • 컬렉션 프레임워크 : 자바에서 데이터(객체형)의 저장과 검색, 조작, 간리를 효율적으로 처리하도록 지원하는 API들의 묶음
  • 모두 java.util 패키지에 있고 크게 Set, List, Map 계열로 구분한다.
  • 상속 관계는 크게 Collection 인터페이스를 상속받는 Set, List 계열과 Map 계열 두 가지가 있다.

 

3. Set 컬렉션

  • Collection 인터페이스에는 기본 method에 추가로 default 예약어와 함께 추가된 method가 존재하는데, 이 method들은 인터페이스의 method임에도 불구하고 내용부를 가지고 있다.
  • 이는 인터페이스에 method를 추가할 경우 이를 상속받는 모든 클래스에 같은 method를 추가해야 한다는 번거로움을 덜기 위해 Java SE 8 version에서 default 예약어를 사용해 인터페이스에서도 내용부를 가진 method를 만들 수 있도록 했기 때문이다.
  • Collection 인터페이스는 다음 URL을 참조 docs.oracle.com/javase/8/docs/api/java/util/Collection.html
 

Collection (Java Platform SE 8 )

Compares the specified object with this collection for equality. While the Collection interface adds no stipulations to the general contract for the Object.equals, programmers who implement the Collection interface "directly" (in other words, create a clas

docs.oracle.com

  • Set 계열은 데이터를 저장한 순서를 기억하지 않고 동일한 데이터를 중복해서 저장하지 못한다.
  • 제네릭을 통해 데이터를 저장할 때 엉뚱한 자료형의 데이터가 추가되는 것을 방지한다.
  • LinkedHashSet은 저장 순서를 기억한다. 그러나 성능 면에서 떨어지기 때문에 저장 순서가 필요한 경우 가급적 List 계열을 쓰는 것이 낫다.
  • SortedSet 계열은 저장된 데이터의 정렬을 지원해 처음과 끝 데이터, 특정 범위의 데이터를 추출할 수 있다. SortedSet 계열은 객체가 생성될 때 정렬에 사용하는 Comparator 인터페이스를 구현한 객체가 필요하다. 지정하지 않으면 내부적으로 정해진 방식에 따라 기본적으로(오름차순) 정렬된다.
  • SortedSet 계열의 대표 클래스로는 TreeSet이 있다.

 

4. List 컬렉션

  • List 계열은 Set 계열과 같이 Collection 인터페이스를 상속받으나 동일한 데이터를 저장할 수 있고, 데이터를 저장한 순서를 기억한다.
  • List 계열을 대표하는 클래스로는 ArrayList, Vector, LinkedList가 있다.
    • ArrayList : 멀티 스레드에 안전하지 않다. 처리 속도가 빠르다. 저장 용량의 증분값을 지정할 수 없다.
    • Vector : 멀티 스레드에 안전하다. 스레드에 대한 안전성을 보장하기 위해 부하가 높다. 저장 용량의 증분값을 지정할 수 있다.
    • LinkedList : List 계열과 Queue/Deque 계열을 모두 구현한다. Queue 계열의 특징을 표현하는 method들이 있다. 스레드에 대한 동기화는 Collections 클래스의 synchronizedList() method를 사용해 wrapping하여 사용한다.

 

5. Map 컬렉션

  • Map 계열은 Set과 List 계열과 달리 하나의 데이터를 저장하지 않고 반드시 키와 값 쌍으로 데이터를 저장해야 한다. 또한 키는 중복을 허용하지 않기에 동일한 키로 데이터를 저장하면 나중에 저장된 값으로 데이터가 변경된다.
  • Map 계열의 대표적인 클래스로는 Hashtable, HashMap, LinkedHashMap, TreeMap이 있다. 특히 Hashtable 클래스를 상속받는 Properties 클래스는 자바의 시스템 정보를 저장하는 용도와 각 프레임워크의 정보를 저장하는 용도로 사용한다.
    • Hashtable  : 멀티 스레드에 대해 안전하다. 즉, 동기화를 지원한다. null의 키를 허용하지 않는다.
    • HashMap : 멀티 스레드에 대해 안전하지 못하다. 동기화가 되지 않는다. null의 키를 허용한다.
    • LinkedHashMap : HashMap에 데이터를 저장하는 순서를 기억하는 기능을 추가한 클래스다. 그래서 HashMap에 비해 부하가 높다. 
    • TreeMap : 키나 맵 구조 자체에 대한 선, 후를 관리할 수 있는 method를 지원한다. 특정 조건으로 정렬할 수 있다.
  • Map 인터페이스의 method는 다음 URL을 참조 docs.oracle.com/javase/8/docs/api/java/util/Map.html
 

Map (Java Platform SE 8 )

If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null. If the function returns null no mapping is recorded. If the function

docs.oracle.com

 

출처 : 헬로 자바 프로그래밍(2016)

728x90