메뉴 건너뛰기

2016.09.13 18:44

컬렉션 프레임워크

조회 수 3705 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄


컬렉션 프레임워크



 인터페이스

 특 징

 List

순서가 있는 데이터의 집합, 데이터의 중복을 허용한다.

--> 데이터를 add하면 앞에서 부터 순차적(순서대로)으로 데이터가 들어간다. 

       그래서 각각의 저장되어 있는 공간들은 고유한 index를 갖는다. 

ex.) 대기자 명단

구현 클래스: ArrayList, LinkedList, Stack, Vector등

 

 Set

순서를 유지하지 않는 데이터의 집합, 데이터의 중복을 허용하지 않는다.

--> 집합이다. 데이터가 순서와는 상관없이 add된다. 중복되지 않는다.

ex.) 양의 정수 집합, 소수의 집합

구현 클래스: HashSet, TreeSet등

 Map

키와 값의 쌍으로 이루어진 데이터의 집합. 순서는 유지되지 않으며, 키는 중복을 허용하지 않고, 값을 중복을 허용한다.

ex.) 우편번호, 지역번호

구현 클래스: HashMap, TreeMap, Hashtable, Properties등


1. 컬렉션 프레임워크란

컬렉션즈 프래임워크라는 것은 다른 말로는 컨테이너라고도 부른다. 즉 값을 담는 그릇이라는 의미이다. 그런데 그 값의 성격에 따라서 컨테이너의 성격이 조금씩 달라진다. 자바에서는 다양한 상황에서 사용할 수 있는 다양한 컨테이너를 제공하는데 이것을 컬렉션즈 프래임워크라고 부른다. ArrayList는 그중의 하나다.


2. 배열과 비교

 배열은 연관된 데이터를 관리하기 위한 수단이었다. 그런데 배열에는 몇가지 불편한 점이 있었는데 그 중의 하나가 한번 정해진 배열의 크기를 변경할 수 없다는 점이다.(배열을 만들고 나서 추후에 배열의 크기를 바꿀수 없다.) 이러한 불편함을 컬렉션즈 프래임워크를 사용하면 줄어든다.


import java.util.ArrayList;

public class ArrayListDemo {

 

    public static void main(String[] args) {

        String[] arrayObj = new String[2];

        // 배열의 크기 지정--> 생성후 변경 불가

        arrayObj[0] = "one";

        arrayObj[1] = "two";

        // arrayObj[2] = "three"; 오류가 발생한다.

        // --> 배열의 크기 변경 불가 (배열은 배열의 크기를 알 때만 사용할 수 있다.)

        for(int i=0; i<arrayObj.length; i++){

            System.out.println(arrayObj[i]);

        }

         

        ArrayList<String> al = new ArrayList<String>(); // <Strinf>: al 참조변수에 추가되는 값이 String 데이터 타입이라는 것을 지정한다.

        // 배열과 비슷하나, 객체 생성후 몇개의 값을 사용할 지 지정할 필요가 없다.

        // --> 여기서 al 참조변수는 컨테이너라고 한다.(자료를 담는 그릇이 된다.) --> 아래의 코드는 add()를 이용하여 al에 one, two, Three를 넣은 모습이다.

        al.add("one");

        al.add("two");

        al.add("three");

        // 값을 추가해도 상관없다. outofbound 에러 없음

        for(int i=0; i<al.size(); i++){// 배열은 length

        // String value = al.get(i);// value 변수에 리턴되는 데이터타입은 ArrayList이므로 String으로 데이터타입 지정시 에러가 발생한다. 

        // 그래서 (String)al.get(i) 또는 ArrayList<String>을 객체 선언시 지정해야 한다. 

            System.out.println(al.get(i));//i=1이면 one, i=2이면 two, 제네릭을 통해서 (String)al.get(i)을 통해 형변환할 필요가 없다.

        }

    }

}

실행결과)

one

two

one

two

three

- ArrayList는 배열과는 사용방법이 조금 다르다. 배열의 경우 값의 개수를 구할 때 .length를 사용했지만 ArrayList는 메소드 size를 사용한다. 

또한, 특정한 값을 가져올 때 배열은 [인덱스 번호]를 사용했지만 컬렉션은 .get(인덱스 번호)를 사용한다.


3. 중복을 허용하는 List/ 중복 허용하지 않는 Set

자료를 꺼낼때 순서가 유지되는지 아닌지 주의있는 보자

import java.util.ArrayList;

import java.util.HashSet; 

import java.util.Iterator;

 

public class ListSetDemo {

 

    public static void main(String[] args) {

        ArrayList<String> al = new ArrayList<String>();

        al.add("one");

        al.add("two");

        al.add("two");

        al.add("three");

        al.add("three");

        al.add("five");

        System.out.println("array");

        Iterator<String> ai = al.iterator(); //<String>에서 제네릭을 선언하지 않았다면 (String)로 형변환을 해야 한다.

        while(ai.hasNext()){

            System.out.println(ai.next());

        }

         

        HashSet<String> hs = new HashSet<String>();

        hs.add("one");

        hs.add("two");

        hs.add("two");

        hs.add("three");

        hs.add("three");

        hs.add("five");

        Iterator<String> hi = hs.iterator();

        System.out.println("\nhashset");

        while(hi.hasNext()){

            System.out.println(hi.next());

        }

    }

}

실행결과)

array

one

two

two

three

three

five

 

hashset

two

five

one

three


4. Map

(1) 예제 1

import java.util.*;


public class MapDemo {

 

    public static void main(String[] args) {

        HashMap<String, Integer> a = new HashMap<String, Integer>();

        a.put("one", 1);// key, value

        a.put("two", 2);

        a.put("three", 3);

        a.put("four", 4);

        System.out.println(a.get("one"));

        System.out.println(a.get("two"));

        System.out.println(a.get("three"));

         

        iteratorUsingForEach(a);

        iteratorUsingIterator(a);

    }

    

    // Map 데이터 iterator 기능 없음 --> Map 데이터 가져오는 방법 1

    static void iteratorUsingForEach(HashMap<String, Integer> map){

        Set<Map.Entry<String, Integer>> entries = map.entrySet();

        for (Map.Entry<String, Integer> entry : entries) {

            System.out.println(entry.getKey() + " : " + entry.getValue());

            //Map 데이터를 가져오는 방법 --> getKey()=key값 ,getValue()=value값

        }

    }

    // Map 데이터 iterator 기능 없음 --> Map 데이터 가져오는 방법 2

    static void iteratorUsingIterator(HashMap<String, Integer> map){

        Set<Map.Entry<String, Integer>> entries = map.entrySet();

        Iterator<Map.Entry<String, Integer>> i = entries.iterator();

        while(i.hasNext()){

            Map.Entry<String, Integer> entry = i.next();

            System.out.println(entry.getKey()+" : "+entry.getValue());

        }

    }

}

Map은 iterator 기능이 없기 때문에 Map의 데이터를 가지고 있는 Set을 만들고 Set에 들어가 있는 데이터 타입은 Map.Entry이다.
(Set에 있는 값은 Map에 있는 값이 대응된다.--> Map에 있는 값을 getKey( ), getValue( )로 알아낸다.) 


(2) 예제2

import java.util.*;


class GenericsEx5

{

public static void main(String[] args) 

{

HashMap<String,Student> map = new HashMap<String,Student>();

map.put("1-1", new Student("자바왕",1,1,100,100,100));

map.put("1-2", new Student("자바짱",1,2,90,80,70));

map.put("2-1", new Student("홍길동",2,1,70,70,70));

map.put("2-2", new Student("전우치",2,2,90,90,90));

Student s1 = map.get("1-1");

System.out.println("1-1 :" + s1.name);

Iterator<String> itKey = map.keySet().iterator();

// key값만 가져오는 경우

while(itKey.hasNext()) {

System.out.println(itKey.next());

}


Iterator<Student> itValue = map.values().iterator();

int totalSum = 0;

// value값만 가져오는 경우

while(itValue.hasNext()) {

Student s = itValue.next();

System.out.println(s);

totalSum += s.total;

}


System.out.println("전체 총점:"+totalSum);

} // main

}


class Student extends Person implements Comparable<Person> { 

String name = ""; 

int ban = 0; 

int no = 0; 

int koreanScore = 0; 

int mathScore = 0; 

int englishScore = 0; 


int total = 0; 


Student(String name, int ban, int no, int koreanScore, int mathScore, int englishScore) { 

super(ban+"-"+no, name);

this.name = name; 

this.ban = ban; 

this.no = no; 

this.koreanScore = koreanScore; 

this.mathScore = mathScore; 

this.englishScore = englishScore; 


total = koreanScore + mathScore + englishScore; 


public String toString() { 

return name + "\t" 

+ ban + "\t" 

+ no + "\t" 

+ koreanScore + "\t" 

+ mathScore + "\t" 

+ englishScore + "\t" 

+ total + "\t"; 


   // Comparable<Person>이므로 Person타입의 매개변수를 선언.

public int compareTo(Person o) { 

  return id.compareTo(o.id);    // String클래스의 compareTo()를 호출

}


} // end of class Student 


class Person  {    

     String id;

     String name;


     Person(String id, String name) { 

         this.id = id;

         this.name = name; 

     }

}

실행결과)
1-1 :자바왕
2-2
1-1
2-1
1-2
전우치 2 2 90 90 90 270
자바왕 1 1 100 100 100 300
홍길동 2 1 70 70 70 210
자바짱 1 2 90 80 70 240
전체 총점:1020

5. Iterator

컬렉션 프레임워크에서 컬렉션에 저장된 요소들을 읽어오는 방법을 표준화 하였다. 컬렉션에 저장된 각 요소에 접근하는 기능을 가진 Iterator인터페이스를 정의하고, Collection인터페이스에는 Iterator

(Iterator를 구현한 클래스의 인스턴스)를 반환하는 iterator()를 정의하고 있다.

public interface Iterator{

boolean hasNext();

Object next();

void remove();

}


public interface Collection{

...

public Iterator iterator();

...

}

iterator()는 Collection인터페이스에 정의된 메서드이므로 Collection인터페이스의 자손인 List와 Set에도 포함되어 있다.

그래서 List나 Set인터페이스를 구현하는 컬렉션은 iterator()가 각 컬렉션의 특징에 알맞게 작성되어 있다. 


List list = new ArrayList();


Iterator it = list.iterator();

while(it.hasNext()){

System.out.println(it.next());

}

ArrayList에 저장된 요소들은 출력하기 위한 코드이다.

ArrayList대신 List인터페이스를 구현한 다른 컬렉션 클래스에 대해서도 이와 동일한 코드를 사용할 수 있다. 첫 줄에서 ArrayList 대신 List인터페이스를 구현한 다른 컬렉션 클래스의 객체를 생성하도록 변경하기만 하면 된다.


Map map = new HashMap();

...

Iterator it = map.keySet().iterator();

Map 인터페이스를 구현한 컬렉션 클래스는 키와 값을 쌍을 저장하고 있기 때문에 iterator()를 직접 호출할 수 없고, 그 대신 ketSet()이나 entrySet()과 같은 메서드를 통해서 키와 값을 각각 따로 Set의 형태로 얻어 온 후에 다시 iterator()를 호출해야 Iterator를 얻을 수 있다.


(1) 예제1

import java.util.*;


class IteratorEx1{

public static void main(String[] args) {

ArrayList list = new ArrayList();

list.add("1");

list.add("2");

list.add("3");

list.add("4");

list.add("5");


Iterator it = list.iterator();

while(it.hasNext()) {

Object obj = it.next();

System.out.println(obj);

}

} // main

} // class

실행 결과)

1

2

3

4

5

List 클래스들은 저장순서를 유지하기 때문에 Iterator를 이용해서 읽어 온 결과 역시 저장 순서와 동일하지만 Set클래스들은 각 요소간의 순서가 유지 되지 않기 때문에 Iterator를 이용해서 저장된 요소들은 읽어와도 처음에 저장된 순서와 같지 않다.


6. 정렬

import java.util.*;


class ArrayListEx1

{

    public static void main(String[] args) 

    {

        ArrayList<Integer> list1 = new ArrayList<Integer>(10);

        list1.add(new Integer(5));

        list1.add(new Integer(4));

        list1.add(new Integer(2));

        list1.add(new Integer(0));

        list1.add(new Integer(1));

        list1.add(new Integer(3));

 

        ArrayList list2 = new ArrayList(list1.subList(1,4)); 

        print(list1, list2);

 

        Collections.sort(list1);    // list1과 list2를 정렬한다.

        Collections.sort(list2);    // Collections.sort(List l)

        print(list1, list2);

 

        System.out.println("list1.containsAll(list2):"+ list1.containsAll(list2));

 

        list2.add("B");

        list2.add("C");

        list2.add(3, "A");

        print(list1, list2);

 

        list2.set(3, "AA");

        print(list1, list2);

         

        // list1에서 list2와 겹치는 부분만 남기고 나머지는 삭제한다.

        System.out.println("list1.retainAll(list2):" + list1.retainAll(list2)); 

        print(list1, list2);

         

        //  list2에서 list1에 포함된 객체들을 삭제한다.

        for(int i= list2.size()-1; i >= 0; i--) {

        //--> for문의 카운터를 0부터 증가시킨 것이 아니라, list2.size()-1 부터 감소시키면서 거꾸로 반복시켰다.

       //만약 카운터를 증가시켜가면서 삭제하면 한 요소가 삭제될 때마다 빈 공간을 채우기 위해 나머지 요소들이 자리이동을 하기 때문에 올바른 결과를 얻을 수 없다. 그래서 카운터를 감소시켜가면서

       //삭제를 해야 자리이동이 발생해도 영향을 받지 않고 작업이 가능하다.

            if(list1.contains(list2.get(i)))

                list2.remove(i);

        }

        print(list1, list2);

    } // main

 

    static void print(ArrayList list1, ArrayList list2) {

        System.out.println("list1:"+list1);

        System.out.println("list2:"+list2);

        System.out.println();       

    }

} // class

실행 결과)

list1:[5, 4, 2, 0, 1, 3] 

list2:[4, 2, 0]


list1:[0, 1, 2, 3, 4, 5] // Collections.sort(List1)을 이용해서 정렬하였다.(Collections는 클래스이다.)

list2:[0, 2, 4]


list1.containsAll(list2):true // list1이 list2의 모든 요소를 포함하고 있는 경우에만 true를 얻는다.

list1:[0, 1, 2, 3, 4, 5]

list2:[0, 2, 4, A, B, C]// add(Object obj)를 이용해서 새로운 객체를 저장하였다.


list1:[0, 1, 2, 3, 4, 5]

list2:[0, 2, 4, AA, B, C]// set(int index, Object obj)를 이용해서 저장된 객체를 변경하였다.


list1.retainAll(list2):true// retainAll의 작업결과로 list1에 변화가 있었으므로 true를 반환한다.

list1:[0, 2, 4]// list2와의 공통 요소 이외에는 모두 삭제되었다.(변화가 있었다.)

list2:[0, 2, 4, AA, B, C]


list1:[0, 2, 4]

list2:[AA, B, C]


List of Articles
번호 제목 날짜 조회 수
91 자바 정규식 마스킹처리 file 2018.06.26 2628
90 개인정보 마스킹처리 (휴대폰번호, 이메일) 2018.06.26 3935
89 자바 날짜 포맷 변환 방법 file 2018.06.21 1424
88 JDK 9에서 eclipse 실행이 안될때 2018.06.05 1595
87 숫자형식 포멧 방법 2018.02.09 2332
86 jquery 스크롤(scroll) 따라다니는 배너 레이어 / 위로 버튼 / 화면 상단으로 이동 / scroll layer 이벤트 file 2017.07.05 4056
85 BigDecimal타입의 사칙연산 2016.12.22 3713
84 다양한 문자 조합을 이용한 카운팅 구하기 2016.12.09 4939
83 자바 JXL 엑셀파일을 읽어 배열리턴 : JAVA EXCEL ArrayList 2016.12.09 4389
82 날짜 시간 포맷 제어 자바 클래스 : JAVA DateUtils Date time file 2016.12.09 5233
81 자바 다양한 형변환. 그리고 아스키 코드 String char int : JAVA 2016.12.09 4188
80 자바 XML 제어 라이브러리 XStream : JAVA 2016.12.09 4917
79 원하는 패턴의 날짜 구하기 : JAVA 2016.12.09 3598
78 iBATIS 동적으로 맵핑하기 2016.12.09 3948
77 GET 파라메타 쿼리문자열 컨트롤 : getQueryString 2016.12.09 4705
76 접근 제한자 private/ protected/ public / default file 2016.10.06 5136
75 예외처리(Exception handling)방법 file 2016.09.21 4584
74 My-SQL 을 이용한 JDBC file 2016.09.21 4282
73 static멤버와 관련된 예제 2016.09.21 3765
72 파일 읽고쓰는 암호화/복호화 2016.09.21 7379
Board Pagination Prev 1 2 3 4 5 6 7 8 Next
/ 8

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved