본문 바로가기

카테고리 없음

(Java) Chapter17. Collections Framework

1. 배열과 컬렉션즈 프레임웍

  배열은 슬롯에 몇 개의 데이터를 담을 수 있는지 알 때만 사용 가능, 만약에 슬롯의 갯수를 정확하게 모른다면 오류가 발생한다. 

  배열과는 달리 CF에서 제공하는 ArrayList는 몇 개의 값을 담을 수 있는지 지정할 필요가 없다

  사용 시 import java.util.ArrayList를 선언 후 사용

package chapter_14;
import java.util.ArrayList;
public class _01_ArrayList {
    public static void main(String[] args) {
//        String[] arrayObj = new String[2];        // 일번적인 array
//        arrayObj[0] = "one";
//        arrayObj[1] = "two";
//        //arrayObj[2] = "three"; // 오류 발생
//        for (int i = 0; i < arrayObj.length; i++) {
//            System.out.println(arrayObj[i]);
//        }
//    }

//        ArrayList a1 = new ArrayList();
//        a1.add("one");
//        a1.add("two");
//        a1.add("three");
//        for(int i = 0; i < a1.size(); i++) {
//            // String value = a1.get(i);  // 오류, "one"은 object 타입임. 근데 이것을 스트링이라는 데이터타입 변수에 저장하려고 해서 오류
//            // > 해결방법: 형변환
//            String value = (String) a1.get(i);  // 이거는 너무 구시대적, 최신 경향은? 제네릭
//            System.out.println(value);
//        }

        ArrayList<String> a1 = new ArrayList<String>();  // 제네릭 적용
        a1.add("one");
        a1.add("two");
        a1.add("three");
        for(int i = 0; i < a1.size(); i++) {
            String value = a1.get(i);
            System.out.println(value);
        }
    }
}

 

2. Collections Framework란?

  컨테이너라고도 부르며 값을 담는 그릇. 값의 성격에 다라 컨테이너의 성격이 조금씩 다름

Collections Framework = Collection(Set, List, Queue) + Map 

출처 : 생활 코딩

  요약하자면, 우리가 다루려고 하는 데이터셋을 다룰 수 있는 컨테이너를 선택적으로 골라 사용해야한다는 것

3. List vs. Set

  1) Set(집합 / 수학의 집합의 특성을 살린 collections)

    - HashSet: ArrayList와 달리 1, 2, 2, 2, 3, 3 의 배열을 저장해도 출력 값은 1, 2, 3 만 나옴 - 고유한 값만 입력되는 것(Set의 특징)

package chapter_14;
import java.util.HashSet;
import java.util.Iterator;
public class _02_HashSet {
    public static void main(String[] args) {
        HashSet<Integer> A = new HashSet<Integer>();
        A.add(1);       // HashSet 에서는1, 2, 3의 개수를 수 없이 늘려도 결과는 1, 2, 3만 나옴
        A.add(2);       // ArrayList 에서는 공통된 숫자를 늘린 만큼 다 추가 됨
        A.add(3);

        Iterator hi = (Iterator) A.iterator();
        while(hi.hasNext()) {
            System.out.println(hi.next());
        }
    }
}

    - 기능 예시

package chapter_14;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
public class _02_HashSet {
    public static void main(String[] args) {
        HashSet<Integer> A = new HashSet<Integer>();
        A.add(1);
        A.add(2);
        A.add(3);

        HashSet<Integer> B = new HashSet<Integer>();
        B.add(3);
        B.add(4);
        B.add(5);

        HashSet<Integer> C = new HashSet<Integer>();
        C.add(1);
        C.add(2);

        System.out.println(A.containsAll(B)); // false, containsAll 은 HashSet 의 고유 메소드, 부분집합
        System.out.println(A.containsAll(C)); // true

        //A.addAll(B);                        // 1, 2, 3, 4, 5 / 합집합 메소드
        //A.retainAll(B);                     // 3 / 교집합
        //A.removeAll(B);                     // 1, 2 / 차집합

        Iterator hi = A.iterator();
        while(hi.hasNext()){
            System.out.println(hi.next());
        }
    }
}

    - 저장된 데이터가 순서대로 저장될 것이라는 보장이 되지 않음 > List 와의 차이2 

 

  2) List

    - ArrayList: 1, 2, 2, 2, 3, 3을 저장하면 중복되어도 출력값은 1, 2, 2, 2, 3, 3 - 저장된 모든 값이 입력됨(List의 특징)

    - 즉, 집합 개념을 도입한 Set과 달리 1차원 행렬 개념을 도입한 Collection

  3) Collections interface

    - Collection, Set, List, Map은 인터페이스이며 하위에는 추상클래스가 존재한다. 또 그 하위에 존재하는 framework들은 상위의 클래스를 상속받은 하위의 클래스들이다. 후자는 하위에 별도의 메소드들을 가지고 있다. 

https://prashantgaurav1.files.wordpress.com/2013/12/java-util-collection.gif

    - 연파랑: 인터페이스, 진파랑: 클래스

    - Set 인터페이스는 비어있는데 이 말은 Collection을 그대로 상속받아 사용한다(순서를 보장받지 못함).

    - List 인터페이스는 별도의 메소드들(API)이 존재하는데 이는 List만 가지는 index와 관련한 특수한 메소드들이다(즉, 순서와 관련).

    - Iterator(반복자): 인터페이스 Collections에 정의되어있는 메소드로 하위의 모든 프레임워크에서 사용 가능함, 메소드 iterator는 인터페이스 iterator를 구현한 객체를 리턴함, 아래 세 가지 메소드를 구현할 것을 강제함

       > hasNext: 반복할 데이터가 더 있으면 true, 더 이상 반복할 데이터가 없다면 false를 리턴한다.

       > next: hasNext가 true라면 next가 리턴할 데이터가 존재한다는 의미이다.

       > remove: 

    - iterator 메소드에서 인스턴스에 저장된 변수들을 출력한다면 내부에서 출력된 값들이 삭제되면서 반복작업이 종료 된다. 즉, 오리지널 데이터 자체는 삭제되지 않고 가상 저장소를 구현하여 기능하는 API

 

  4) Map

    - Key(중복 불가, 정의역) + value(중복 가능, 공역) = Map(치역)

    - 수학의 함수와 같은 개념을 구현 (y = f(x))

    - entrySet: Map > Set으로 전환 (Set의 메소드 사용 가능, iterator)

    - 두 가지 데이터 열을 가지므로 제네릭도 두 가지 정의

package chapter_14;
import java.util.*;
public class _03_HashMap {
    public static void main(String[] args) {
        HashMap<String, Integer> a = new HashMap<String, Integer>();  // hashmap 은 key 와 value 의 관계를 다루기 때문에 두 개의 제네릭을 가짐
        a.put("one", 1);        // put 은 Map 인터페이스에만 존재함, (key, value)
        a.put("two", 2);
        a.put("three", 3);
        a.put("four", 4);
        System.out.println(a.get("one"));   // 1, value 를 불러오기위한 도구로 사용되므로 key 는 중복이 불가하다
        System.out.println(a.get("two"));   // 2
        System.out.println(a.get("three")); // 3

        iteratorUsingForEach(a);
        iteratorUsingIterator(a);
    }

    static void iteratorUsingForEach(HashMap map){
        Set<Map.Entry<String, Integer>> entries = map.entrySet(); // entrySet: map 안의 정보를 set 형식으로 바꿈
        for (Map.Entry<String, Integer> entry : entries) {        // entries는 Set의 데이터타입
            System.out.println(entry.getKey() + " : " + entry.getValue());
            // getKey(): string 데이터타입, 해당하는 데이터를 하나씩 꺼내 씀
            // getValue(): Integer 데이터타입, 상동
            // four : 4 / one : 1 / two : 2 / three : 3
        }
    }

    static void iteratorUsingIterator(HashMap map){
        Set<Map.Entry<String, Integer>> entries = map.entrySet();
        Iterator<Map.Entry<String, Integer>> i = entries.iterator(); // set 으로 변환했기 때문에 iterator 사용 가능
        while(i.hasNext()){
            Map.Entry<String, Integer> entry = i.next();
            System.out.println(entry.getKey()+" : "+entry.getValue());
            // four : 4 / one : 1 / two : 2 / three : 3
        }
    }
}

  5) 정렬(인터페이스 Comparable)

package chapter_14;
import java.util.*;

class Computer implements Comparable{       // public interface, sort 메소드 사용
    int serial;
    String owner;
    Computer(int serial, String owner){
        this.serial = serial;
        this.owner = owner;
    }
    public int compareTo(Object o) {        // Comparable 은 compareTo를 정의할 것을 강제하는 인터페이스
        return this.serial - ((Computer)o).serial;  // 비교 객체가 기준 객체와 같으면 0, 보다 크면 양수, 작으면 음수로 출력
    }
    public String toString(){
        return serial+" "+owner;
    }
}

public class _04_collectionsSort {
    public static void main(String[] args) {
        List<Computer> computers = new ArrayList<Computer>();
        computers.add(new Computer(500, "egoing"));
        computers.add(new Computer(200, "leezche"));
        computers.add(new Computer(3233, "graphittie"));
        Iterator i = computers.iterator();
        System.out.println("before");
        while(i.hasNext()){
            System.out.println(i.next());   // 위의 순서대로 출력
        }
        Collections.sort(computers);        // sort는 list 타입만 받음
        System.out.println("\nafter");
        i = computers.iterator();
        while(i.hasNext()){
            System.out.println(i.next());   // 숫자 순서대로 나열 
        }
    }
}