
컬렉션은 애플리케이션의 작성을 도와주는 중요한 도구로써 자료를 저장 하기 위한 구조다.
크기가 동적으로 바뀌는 것들은 컬렉션을 쓴다.
많이 사용되는 자료 구조로는 list,stack,queue,set,hash table등이 있다.
컬렉션의 종류(중요한 것들)
List(ArrayList, LinkedList)는 동적 배열을 정의하고 있다.
Set(HashSet)은 집합을 정의하고 있다.
Map(hasMap)은 키가 주어지면 값을 반환하는 사전과 같은 자료구조를 정의하고 있다.
벡터
컬렉션의 일종으로 가변 크기의 배열을 구현하고 있다. 즉 요소의 개수(인덱스 값)이 늘어나면 자동으로 배열의 크기가 늘어난다.
또한 제네릭 기법을 사용하고 있어 어떤 객체라도 저장 가능하며 정수와 같은 기초형 데이터도 오토박싱 기능을 이용하여서 객체로 변환되어 저장 할 수 있다.
스레드간의 동기화를 지원한다.
- 문법으로는
- 값을 추가하려면 add(),
- 값을 집어넣을때는add(index, object),
- 값을 추출 할 때는 get()
- 값들의 개수를 반환 할때는 size()
예제
package ex13;
import java.util.Collections;
import java.util.Vector;
public class VectorExample1 {
public static void main(String[] args) {
Vector<String> vec = new Vector();
vec.add("Apple");
vec.add("Orange");
vec.add("Mango");
// 크기
System.out.println(vec.size());
// 인덱스 접근
System.out.println(vec.get(1));
// 정렬 (오름차순)
Collections.sort(vec);
for (String s : vec) {
System.out.print(s + " ");
}
System.out.println();
// 정렬 (내림차순)
Collections.sort(vec, Collections.reverseOrder());
for (String s : vec) {
System.out.print(s + " ");
}
System.out.println();
// 다른 방법의 정렬(일반 배열)
// Arrays.sort();
// 삭제
String result = vec.remove(2);
System.out.println(result);
System.out.println(vec.size());
// 값 찾기
boolean search =vec.contains("Mango");
System.out.println(search);
String a = "Mango";
boolean check = a.equalsIgnoreCase("mAngo");
System.out.println(check);
}
}

AraayList(내가 찾으려는 값을 바로 찾아낼 수 있다.)(중요)
동시에 접근이 가능하다.
스레드간의 동기화를 하지 않는다.
제네릭 클래스로 제공이 되기 때문에 생성하려면 타입 매개 변수를 지정 해야 한다.
일반 클래스로 저장 타입을 가져 갈 수 도 있다.
생성 문법으로는
ArrayList<저장 타입> list = new ArrayList<저장 타입>():
배열을 리스트로 변경 할 때는 (밑 문법 )사용List<String> list = Arrays.asList(new String[size]);
- 문법으로는
- 데이터를 저장 하려면 add(저장할 값),
- 기존의 데이터가 들어 있는 위치를 지정해서 add(index, object),를 호출하면 새로운 데이터는 중간에 삽입
- 값을 변경하고 싶을 때는 set(index, object)을 사용한다.
- 인덱스의 저장된 값을 추출 할 때는 자료타입 변수명 = get(index)을 사용한다.
- 만일 이때 범위를 벗어나는 인덱스를 사용하면
- 데이터를 삭제하려면 remove(index)를 사용한다.
- add( )메서드: 새로운 값의 추가가 큐의 용량을 넘어서지 않으면 값을 추가한다.
- reomove( )와 poll( )은 큐의 처음에 있는 값을 제거하거나 가져온다. 어떤 값이 제거가 되냐는 큐의 정렬 정책에 따라 달라진다.
- element( )와 peek( )는 큐의 처음에 있는 값을 삭제하지 않고 가져온다.
- 정렬은 데이터를 어떤 기준에 의하여 순서대로 나열 하는 것이다
- 정렬 알고리즘에는 퀵 정렬, 합병 정렬, 히프 정렬 등의 다양한 방법이 존재한다.
- Collections 클래스의 정렬은 합병 정렬을 이용한다.
- 합병 정렬은 시간복잡도가 O(nlog(n))이며 정렬된 리스트에 대해서는 상당히 빠르다.
- Collections 클래스의 sort( )는 List인터페이스를 구현하는 컬렉션에 대하여 정렬을 수행 한다.
- String 타입이면 알파벳 순서대로 Date타입이라면 시간 순서대로 이렇게 가능한 이유는 Comprable 인터페이스를 구현 하기 때문이다. Comprable 인터페이스는 메서드(밑 코드)만을 가지고 있다.
예제
package ex13;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArrayListEx01 {
public static void main(String[] args) {
List<Integer>arr = new ArrayList();
List<Integer>arr2 = Arrays.asList(1,2);
}
}

LinkedList(왠만해서 사용 x 앞의 인덱스를 들려서 내가 찾으려는 인덱스를 찾는다)
각 인덱스 값을 링크로 연결한다. 이렇게 해서 linkedlist는 중간에 값을 삽입하거나 삭제되는 위치의 바로 앞에 있는 값의 링크 값 만을 변경하면 된다.
즉 배열의 값을 넣을 때 앞에 인덱스 번호를 붙인다.
그러므로 삽입이나 삭제가 빈번하게 일어날 때는 LinkedList를 사용하는게 좋다.
그러나 인덱스를 가지고 원소를 접근하는 연산은 ArrayList가 더 빠르다.
예제
package ex13;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String>list = new LinkedList<String>();
list.add("MILK");
list.add("BREAD");
list.add("BUTTER");
list.add(1,"APPLE"); // 인덱스 1에 "APPLE"을 삽입
list.add(2,"GRAPE"); // 인덱스 2에 "GRAPE"를 삽입
list.remove(3); // 인덱스 3의 값을 삭제 한다.
for (int i = 0; i< list.size(); i++)
System.out.println(list.get(i)+"");
}
}
Set(중요)
앞에서 설명한것들은 다 순서의 의해서 값이 저장되지만 순서의 상관없이 값을 저장할때는
Set(집합)
을 사용한다.
Set은 동일한 데이터를 중복해서 가질 수 없다.
HashSet은 해쉬 테이블에 값을 저장한다.
수학에서 집합연산에 합집합, 교집합이 있는 것처럼 , Set에도 addAll()과 retainAll()이라는 메소드로 각각 합집합, 교집합을 구현한다.예제
package ex13;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
HashSet<String>set = new HashSet<String>();
set.add("Milk");
set.add("Bread");
set.add("Butter");
set.add("Cheese");
set.add("Ham");
set.add("Ham");
System.out.println(set);
if (set.contains("Ham")){
System.out.println("Ham도 포함되어 있음");
Set<Integer> s1 = new HashSet<>(Arrays.asList(1,2,3,4,5,7,9));
Set<Integer> s2 = new HashSet<>(Arrays.asList(2,4,6,8));
s1.retainAll(s2); //교집합 계산
System.out.println(s1);
}
}
}

Map(HashMap)(중요)
Map은 키-값을 하나의 쌍으로 묶어서 저장하는 자료구조이며 키(단어), 값(단어에 대한 설명)이 있다.
제한적으로는 중복된 키를 가질 수 없다. 각 키는 오직 하나의 값에만 매핑 될 수 있다.
키가 제시되면Map은 값을 반환한다.
list와 같은 자료구조와는 다르기 때문에 Collecttion 인터페이스를 사용하지 않고
별도의 Map이라는 이름의 인터페이스가 제공된다.
HashMap
은 해싱 테이블에 데이터를 저장하고 키들을 정렬된 순서로 방문할 필요가 없을때 사용한다. 데이터를 저장하려면 put()메소드를 사용한다.
초기화 할때는 (밑 코드)를 사용한다.Map<INTEGER,String> map = Map.of("kim","1234","park","pass","lee","world")
예제
package ex13;
import java.util.HashMap;
import java.util.Map;
public class MapTest {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("kim","1234");
map.put("park","pass");
map.put("lee","word");
System.out.println(map.get("lee")); // 키를 가지고 값을 참조한다.
for (String key:map.keySet()){ //keySet()은 키들의 집합을 반환한다. 모든 항목을 방문한다.
String value = map.get(key);
System.out.println("key="+key+",vlaue="+value);
}
map.remove(3); //하나의 항목을 삭제한다.
map.put("choi","password"); //하나의 항목을 대치한다.
System.out.println(map);
}
}

Map에 저장된 데이터를 꺼내는 코드는 다른 컬렉션과는 다르다.
예제
for (String key: map.keySet()){
System.out.println("key="+key+", value="+map.get(key));
//for-each 구문과 keySet()을 사용하는 방법
map.forEach((key, value) -> {
System.out.println("key="+key+", value="+value);
});
//람다 표현식
Queue
큐는 데이터를 처리하기 전에 잠시 저장하고 있는 자료 구조로 후단 에서 원소를 추가하고 전단에서 값을 추가하여 FIFO(first-in-first-out)형식으로 저장한다.
예외적으로 우선순위 큐는 값들을 우선순위에 따라 저장한다.
큐는 인터페이스 이며 3개 클래스(ArrayDeque, LinkedList, PriorityQueue)가 있다.
이중에서 다큐는 전단과 후단에서 모든 값을 추가하거나 삭제 할 수 있다.
Queue 메서드
예제
package ex13;
import java.util.LinkedList;
import java.util.Queue;
public class QueueTest {
public static void main(String[] args) {
Queue<Integer> q = new LinkedList<>();
for (int i = 0; i < 5; i++) {
q.add(i);
}
System.out.println("큐의 요소: "+q);
int e = q.remove();
System.out.println("삭제된 요소:"+ e);
System.out.println(q);
}
}

Collections 클래스
Collections 클래스는 여러 알고리즘을 알고리즘을 구현한 메서드들을 제공한다.
이 메서드들은 제네릭 기술을 사용하여서 작성되었으며 정적 메서드의 형태로 되어 있다. 메서드의 첫 번째 매개 변수는 알고리즘이 적용되는 컬렉션이 되며 이중에서 중요한 알고리즘은 정렬(Sorting), 섞기(Shuffling), 탐색(Searching)이 있다.
정렬
public interface Comprable<T> {
public int compareTo(T o);
}
compareTo()메서드는 매게 변수 객체를 현재의 객체와 비교하여 음수 (작을때)
0(같을때),양수(클때)를 반환한다.
문자열 정렬
package ex13;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Sort {
public static void main(String[] args) {
String[] sample = {"i", "walk", "the", "line"};
List<String>list = Arrays.asList(sample); // 배열을 리스트로 변경 asList()사용
Collections.sort(list);
System.out.println(list);
}
}
StudentEmployee(compareTo( ))를 구현)
package ex13;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
class Student implements Comparable<Student>{
int number;
String name;
public Student(int number, String name){
this.number=number;
this.name=name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
public int compareTo(Student s){
return s.number-number;
}
}
public class SortTest {
public static void main(String[] args) {
Student array[]= {
new Student(2,"김철수"),
new Student(3,"이철수"),
new Student(1,"박철수"),
};
List<Student> list = Arrays.asList(array);
Collections.sort(list);// 만약 역순으로 정렬하기를 원한다면 Collections.sort(list,Collections.reverseOrder())를 사용
System.out.println(list);
}
}
섞기
리스트에 존재하는 정렬을 파괴하여서 값들의 순서를 랜덤 하게 만든다.
게임을 구현할 때 유용하게 사용 된다.
예제
package ex13;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Shuffle {
public static void main(String[] args) {
List<Integer>list = new ArrayList<Integer>();
for (int i=1; i<=10; i++){
list.add(i);
}
Collections.shuffle(list);
System.out.println(list);
}
}

탐색
탐색이란 리스트 안에서 원하는 값을 찾는 것 이다. 만약 리스트가 정렬돼있지 않다면
처음부터 모든 값을 방문 할 수 밖에 없다(선형 탐색) 하지만 리스트가 정렬 돼있다면
중간에 있는 원소와 먼저 비교 하는 것 이 좋다(이진탐색) 만약 중간 원소보다 찾고자 하는 원소가 크면 뒷 부분에 있고 반대이면 앞 부분에 있다.
만약 반환값이 양수이면 탐색이 성공한 객체의 위치이다collec.get(index)하면 원하는 객체를 얻을 수 있다. 만약 반환값이 음수이면 탐색이 실패했다. 그러나 도움이 되는 정보가 반환 되는데 반환 값에서 현재의 데이터가 삽입될 수 있는 위치를 알아낼 수 있다. 반환 값이pos이면 (-pos -1)이 삽입 위치가 된다.(밑 코드 문법)
int pos = Collections.binarySearch(list,key);
if(pos<0)
list.add(-pos-1);
예제
package ex13;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Search {
public static void main(String[] args) {
int key = 50;
List<Integer> list = new ArrayList<Integer>();
for (int i =0; i<100; i++){
list.add(i);
}
int index = Collections.binarySearch(list,key);
System.out.println("탐색의 반환 값 ="+index);
}
}

Share article