●컬렉션 클래스
-자료구조를 구현하고 있는 클래스
-자료 구조 : 각각의 데이터들을 효율적으로 저장하고 운용하기 위한 방법론을 실제 구현하기 위한 구조
1.배열
- 다수개의 요소를 저장할 수 있음. 번호(첨자)에 의해 손쉬운 접근 방법을 제공
- 크기가 고정, 데이터의 중간삽입과 중간삭제에 비효율적
2.리스트 (List)
- 크기의 제약없이 데이터를 저장할 수 있음, 데이터의 삽입과 삭제에 최적화
- 검색에 취약 - 참조값(주소)을 저장하기 때문에
- 이를 개선하기 위한 더블 링크드 리스트를 사용하기도 함
- 데이터 저장 시 불필요한 메모리 사용
자바의 모든 자료구조 클래스(컬렉션 클래스)들은 java.util 패키지를 통해 제공받을 수 있음
-위와 같은 동적 배열을 구현하고 있는 클래스들 - Vector, ArrayList(가장 많이 사용)
Vector, ArrayList 클래스
- 두 개의 클래스는 동일한 기능을 제공
- 쓰레드 동기화의 지원여부 크기의 제약없이 데이터를 저장(동적으로 크기를 확장)
-배열과 같이 인덱스를 기반으로 데이터를 접근
-데이터의 중복을 허용
-데이터의 입력 순서를 유지
링크드 리스트를 구현하고 있는 클래스 - LinkedList
3. Set 타입의 저장방법을 구현하고 있는 클래스들
Set 타입 : 데이터를 저장할 때, 중복을 허용하지 않는 방법:
검색을 위해서 사용, 중복된 값을 제거하기 위해서 사용
-HashSet(사용빈도 : 중) , TreeSet
4. Map 타입의 저장방법을 구현하고 있는 클래스들
-Map 타입 : 데이터를 Key와 Value의 형태로 저장하는 방법
(검색을 위해서 사용, key 의 값은 중복을 허용하지 않음, Value의 값은 중복을 허용)
-HashTable, HashMap (가장 많이 사용)
●Vector, ArrayList 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class Formatter03 {
public static void main(String[] args) {
//동적 배열의 객체 생성 초기값으로 크기를 지정할 수 있지만 통상 크기 지정없이 사용합니다
Vector v = new Vector();
ArrayList a = new ArrayList();
//데이터 입력 add 메소드를 사용하여 데이터를 입력
v.add(10);
v.add(20);
v.add(30);
//데이터의 저장은 add 로 저장하는 데이터의 레퍼런스 값을 저장합니다.
a.add(10);
a.add(20);
a.add(30);
//현재 add에 사용된 10,20,30은 int 자료가 아니라 Integer 자료입니다.
for(int i=0; i<v.size(); i++)
System.out.printf("v[%d] = %d\t\t",i,v.get(i));
for(int i=0; i<a.size(); i++)
System.out.printf("a[%d] = %d\t\t",i,a.get(i));
|
cs |

a.set(2, 100); //2번 인덱스의 값을 100으로 수정
for(int i=0; i<a.size(); i++)
System.out.printf("a[%d] = %d\t\t",i,a.get(i));
a.add(2,300); //2번을 밀어내고 그자리에 300을 추가
for(int i=0; i<a.size(); i++)
System.out.printf("a[%d] = %d\t\t",i,a.get(i));
a.remove(1); //1번 인덱스의 내용 20 제거
for(int i=0; i<a.size(); i++)
System.out.printf("a[%d] = %d\t\t",i,a.get(i));
●컬렉션 클래스 저장 방식
-모든 컬렉션 클래스들은 기본적으로 Object 타입을 저장/반환할 수 잇습니다.
Object 타입을 매개변수 사용하는 모든 컬랙션 클래스들은 타입에 상관없이 저장할 수 있습니다.
-하지만, 저장된 데이터를 반환 받는 과정에서 런타임에러가 발생될 수 있습니다
-Object -> 자식 클래스의 타입 : 강제 형변환이 필요
1
2
3
4
5
6
7
8
9
10
11
|
public class Formatter03 {
public static void main(String[] args) {
ArrayList a = new ArrayList();
a.add(10)
a.add(1.1);
a.add("Hello");
Integer i0 = (Integer)a.get(0);
Double i2 = (Double)a.get(1);
String i3 = (String)a.get(2);
|
cs |
-> 위와 같이 하나의 ArrayList 에 여러 자료형태를 섞어서 저장하고 사용할 수 있습니다.
다만 자료형을 섞어서 저장하고 사용할 경우 위의 에러 내역과 같이 꺼내고,
형변환시 자료형이 맞지 않아 에러가 발생하거나 형변환을 하지 않아 에러가 발생할 확률이 높아집니다.
그래서 보통은 자료형을 하나로만 통일해서 저장하는 형식을 사용하게 되고,
규칙으로 만들어 지정한 자료형이 저장되지 못하도록 사용하기도 합니다.
1
2
3
4
5
6
7
8
9
|
public class Formatter03 {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(100);
//get()으로 자료를 꺼낼 때 강제 형변환이 없어도 됩니다.
Integer i = list.get(0);
|
cs |
-> 제네릭 문법
-제네릭이 적용이 안된 상태로 동일한 이름의 클래스이지만
객체 생성 시점에 ... 자료형을 지정하여 서로 다른 자료형을 지원하는 클래스를 생성할 수 있는
문법입니다 (메소드 오버로딩과 유사한 문법)
-제네릭 문법을 사용한 ArrayList 클래스의 객체 생성 예시
ArrayList<Integer> a = new ArrayList<Integer>();
(new 다음의 클래스명에서는 제네릭 타입을 생략할 수 있음)
ArrayList<Integer> a = new ArrayList<>();
● HashSet 클래스
-데이터의 중복을 허용하지 않고 저장하는 클래스
- 검색을 위해서 사용되는 클래스
(저장할 때 hash 연산의 결과로 저장하니, 검색할 때도 hash 연산 결과로 검색하여 빠른
검색이 가능)
-hash 연산 : 클래스 내에서 유일한 값을 얻어 낼 수 있는 고유 알고리즘 연산
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public class Formatter03 {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>();
v.add(1); v.add(2); v.add(2);
System.out.println(v.size()); //중복을 허용하기 때문에 3이 출력
ArrayList<Integer> a = new ArrayList<>();
a.add(1); a.add(2); a.add(2);
System.out.println(a.size()); //중복을 허용하기 때문에 3이 출력
HashSet<Integer> h = new HashSet<>();
h.add(1); h.add(2); h.add(2);
System.out.println(h.size()); //중복을 허용하지 않기 때문에 2이 출력
|
cs |
- HashSet 클래스로 로또 번호 출력하기
1
2
3
4
5
6
7
8
9
10
|
public class Formatter03 {
public static void main(String[] args) {
HashSet<Integer> lotto = new HashSet<>();
while( lotto.size() < 6) {
lotto.add( (int)(Math.random() * 45) + 1);
} //size가 6개로 채워질때까지 반복
for(Integer i : lotto)
System.out.printf("%d ",i);
|
cs |

-> 해쉬세트 콜렉션에는 sort메서드가 없습니다.
따라서 부모클래스인 List 클래스에 전해줘서 리스트 변환과정을 거치고
Collections.sort로 정렬을 수행해야 합니다
1
2
3
4
5
6
7
8
|
public class Formatter03 {
public static void main(String[] args) {
List<Integer> list = new LinkedList(lotto);
Collections.sort(list); //Collection 클래스의 static 메서드인 sort를 이용하여 정렬
System.out.println(list);
|
cs |

● HashSet 타입의 객체 내부를 순회하는 방법
1. Iterator 객체를 사용하는 방법
1
2
3
4
5
6
7
8
9
10
|
public class Formatter03 {
public static void main(String[] args) {
Iterator<Integer> iter = lotto.iterator();
//lotto 해시세트의 각 요소 방문 권한을 iter라는 객체에 전달하여 방문하는 방식
while(iter.hasNext() ) //iter.hasNext() : 다음 데이터가 있으면 true 리턴
System.out.printf("%d ",iter.next());
|
cs |

2. for문을 이용하는 방법
1
2
3
4
5
6
|
public class Formatter03 {
public static void main(String[] args) {
for( Integer i : lotto)
System.out.printf("%d ", i);
|
cs |
●Hashtable, HashMap 클래스
-데이터베이스 내부의 키 값을 검색하기 위해서 만들어진 알고리즘을 기반으로 작성된 클래스
- 검색을 위해서 사용되는 클래스
-key, Value를 저장할 수 있는 클래스
-key는 중복을 허용하지 않습니다
-Value는 중복을 허용합니다
저장 예
HashMap hm = new HashMap();
hm.put(1, "One"); hm.put(2, "Two"); hm.put(3,"Three");
-key 값은 중복이 안되므로 , 만약 중복되는 키값을 사용할 시 데이터가 대체 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class Formatter03 {
public static void main(String[] args) {
//Key 값은 문자열, Value값은 정수로 입력받는 Hashtable 객체 생성
Hashtable<String, Integer> ht = new Hashtable<>();
//Key 값은 정수, Value 값은 문자열로 입력받는 HashMap 객체 생성
HashMap<Integer, String> hm = new HashMap<>();
hm.put(1, "One");
//hm.put("One", 1); //에러 , 객체 생성시에 제약된 제네릭형식에 맞지 않아서
hm.put(2, "Two");
hm.put(3, "Three");
ht.put("One",1);
ht.put("Two",2);
ht.put("Three",3);
System.out.printf("\"Three\" = %d\n",ht.get("Three"));
System.out.printf("3 = %s\n",hm.get(3));
|
cs |

●Hashtable, HashMap 클래스 내부의 데이터를 반복문을 통해서 접근하는 예
1. Enumeration 타입을 사용하는 방법
Enumeration은 열거형 자료형식(인터페이스) 입니다
1
2
3
4
5
6
7
8
9
10
|
public class Formatter03 {
public static void main(String[] args) {
Enumeration<String> e1 = ht.keys(); //키들의 접근 권한을 저장
while(e1.hasMoreElements()) {
String key = e1.nextElement(); //키값 하나를 꺼내서 String 변수에 저장
int value = ht.get(key); // 키값으로 검색한 벨류값을 얻어냅니다
System.out.printf("key(%s)=Value(%d)",key,value);
}
|
cs |

2. for문을 활용하여 key 값을 순회하는 방법
1
2
3
4
5
6
|
public class Formatter03 {
public static void main(String[] args) {
for(Integer k : hm.keySet()) { //hm.ketSet() : 키값들만 모아서 리스트로 생성
String v = hm.get(k);
System.out.printf("key(%d)=Value (%s) ",k,v);
|
cs |

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
class Point{
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return "x:" + x + ",y:" + y;
}
public boolean equals(Object obj) {
if( !(obj instanceof Point)) return false;
Point p = (Point)obj;
boolean result = this.x == p.x && this.y == p.y;
return result;
}
}
public class Collection06 {
public static void main(String[] args) {
ArrayList<Point> list = new ArrayList<Point>();
Point p1 = new Point(10,20);
list.add(p1);
list.add( new Point(20,20));
list.add( new Point(30,30));
for(Point p : list)
System.out.println(p.toString());
int index = list.indexOf(new Point(30,30));
//.indexOf() : ArrayList의 멤버 메서드이고, 괄호 안에 넣은 객체 내지 값이
//몇번째 요소로 있는지 인덱스값을 리턴합니다. 없으면 -1을 리턴합니다.
System.out.printf("(30,30)의 위치 : %d\n", index);
boolean con = list.contains( new Point(30,30));
System.out.printf("(30,30)의 저장 유무 : %b\n",con);
//사용자 정의 클래스에 equals 메소드가 오버라이딩 되어있지 않은 경우
//컬렉션 내부에서 동일한 형태의 객체를 검색 및 비교할 수 없습니다.
//참조값끼리 비교되어 의도와 다른 결과를 얻습니다.
//equals 메서드를 오버라이딩해주니까 제대로 결과가 나옵니다
}
}
|
cs |
-> ArrayList 객체의 값으로 Point 객체만 저장이 가능
->만약 Point 클래스에 equals 메소드가 오버라이딩 되어 있지 않았다면 indexOf 와 contains 메소드가
제기능을 못함 (참조변수의 주소끼리 비교하는 결과를 낳기 때문)
'JAVA > 수업 복습' 카테고리의 다른 글
자바 공부기록 53 - Interface (0) | 2022.05.12 |
---|---|
자바 공부기록 52 - Abstract 추상 클래스 (0) | 2022.05.12 |
자바 공부기록 50 - WrapperClass - Integer 클래스, BigInteger 클래스 (0) | 2022.05.11 |
자바 공부기록 49 - Formatter (0) | 2022.05.11 |
자바 공부기록 48 - StringClass (0) | 2022.05.11 |