728x90
컬렉션 프레임워크
데이터를 효율적으로 다루기 위한 클래스들의 집합
Iterable
자바 컬렉션 프레임워크에서 컬렉션에 저장되어 있는 요소들을 읽어오는 방법을 표준화 한 것
Iterable forEach -> next();, hasNext(), remove();
List(ArrayList, LinkedList, Vector)
- 동일한 타입의 여러 원소를 선형 집합으로 관리하는 동적 데이터 구조
- 요소 추가, 삭제됨에 따라 크기가 변경될 수 있음
- List Interface 구현체에 따라 특성이 다름
ArrayList
인덱스를 통한 요소 접근이 빠름
원소 삽입/제거가 느림
LinkedList
인덱스를 통한 요소 접근이 느림
원소 삽입/제거가 빠름
Vector
ArrayList 이전 사용 클래스
스레드 동기화 지원이되므로 속도가 비교적 느림
ArrayList : 동적 배열을 사용한 List 구현 클래스
- 요소가 추가될 때 배열에 남은 공간이 없다면 크기를 일정 배수로 늘린 배열을 만들어 기존 요소를 옮김
- 배열 크기를 지정하지 않으면 10개의 배열이 기본적으로 만들어짐
- 용량이 부족할 경우 요소 추가 시 1.5배 크기 정도의 배열을 새로 생성하여 기존 항목을 복사함
- 요소가 배열에 저장되어 있기 때문에 지정한 위치의 요소 접근이 빠름
- 중간 위치의 요소 삽입/제거 연산은 기존 배열 연산과 같이 해당 위치 이후의 모든 요소를 이동시키므로 느림
package test21;
import java.util.ArrayList;
class Stack{
//스택 : 가장 나중에 들어온 자료가 가장 먼저 나가는 구조(Last-In First Out)
//데이터 저장 push(), 데이터 꺼내기 pop()
private ArrayList<String> arrayStack = new ArrayList<String>();
//스택 맨 뒤에 요소를 추가 메소드
public void push(String data) {
arrayStack.add(data);
}
//스택의 맨 뒤에서 요소를 꺼내는 메소드
public String pop() {
int len = arrayStack.size();
if(len == 0) {
System.out.println("스택이 비었습니다.");
return null;
}
return arrayStack.remove(len-1);
}
}
public class StackTest1 {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
}
package test21;
import java.util.ArrayList;
class Queue{
private ArrayList<String> arrayQueue = new ArrayList<String>();
//큐 : 처음 들어온 자료가 가장 먼저 나가는 구조 First In First Out
//enQueue(), deQueue()
public void enQueue(String data) {
arrayQueue.add(data);
}
public String deQueue(){
int len = arrayQueue.size();
if(len ==0) {
System.out.println("큐가 비었습니다.");
return null;
}
return arrayQueue.remove(0);
}
}
public class QueueTest1 {
public static void main(String[] args) {
Queue queue = new Queue();
queue.enQueue("A");
queue.enQueue("B");
queue.enQueue("C");
System.out.println(queue.deQueue());
System.out.println(queue.deQueue());
System.out.println(queue.deQueue());
System.out.println(queue.deQueue());
}
}
LinkedList : 차례로 연결된 node를 사용한 구현체
- 요소가 추가/삭제 될 때마다 해당 요소의 node가 추가/삭제됨
- 지정된 위치의 요소에 접근하기 위해서는 선형 탐색이 필요
- 순차적인 접근 시 Iterator를 사용해 효율적으로 관리
- 중간 위치의 요소 삽입/제거 연산은 해당 node와 연결된 참조값만 갱신하여 다른 node에 영향을 미치지 않음
package test21;
import java.util.ArrayList;
import java.util.LinkedList;
public class LinkedListTest1 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<String>();
list.add("A");
list.add("B");
list.add("C");
System.out.println("list : " + list);
System.out.println();
list.add(1, "D");
System.out.println("list : " + list);
System.out.println();
list.addFirst("0");
System.out.println("list : " + list);
System.out.println();
list.addLast("E");
System.out.println("list : " + list);
System.out.println();
System.out.println("list 첫번째 요소 삭제 : " + list.removeFirst());
System.out.println(list);
System.out.println("list 마지막 요소 삭제 : " + list.removeLast());
System.out.println(list);
//ArrayList, LinkedList 속도 차이
//처음 데이터 추가(100000개 추가)
ArrayList<Integer> alist = new ArrayList<Integer>();
LinkedList<Integer> llist = new LinkedList<Integer>();
for(int i = 0 ; i < 1000000; i++) {
alist.add(i);
llist.add(i);
}
System.out.println();
System.out.println("ArrayList Access");
long start = System.currentTimeMillis();
//alist 가져오기
for(int i = 0; i<alist.size();i++) {
alist.get(i);
}
long end = System.currentTimeMillis();
System.out.println(end -start);
System.out.println();
System.out.println("LinkedList Access");
long start1 = System.currentTimeMillis();
for(int i =0; i<llist.size();i++) {
llist.get(i);
}
long end1 = System.currentTimeMillis();
System.out.println(end1 - start1);
System.out.println();
//중간에 데이터 삽입 시 처리 속도
System.out.println("ArrayList 삽입 시 처리 속도");
long start2 = System.currentTimeMillis();
for(int i = 0; i< 100000; i++) {
alist.add(500,i); //500번째 삽입
}
long end2 = System.currentTimeMillis();
System.out.println(end2-start2);
System.out.println("LinkedList 삽입 시 처리 속도");
long start3 = System.currentTimeMillis();
for(int i = 0; i< 100000; i++) {
llist.add(500, i);
}
long end3 = System.currentTimeMillis();
System.out.println(end3-start3);
//초기화 속도 ArrayList > LinkedList
//삽입 시 처리 속도 ArrayList < LinkedList
//LinkedList : ArrayList에 비해 중간에 데이터를 삽입, 삭제하는 데 걸리는 시간이 빠름
// 크기를 동적으로 증가 시키게 되고 각 요소는 요소의 자료와 다음 요소의 주소를 저장하는 부분으로 구현됨
}
}
Vector
package test21;
import java.util.Iterator;
import java.util.Vector;
public class VectorTest1 {
public static void main(String[] args) {
//ArrayList 이전 사용되던 List 자료구조
//2개 이상의 스레드가 동시에 vector에 사용하는 경우에 오류가 나지 않도록 동기화를 지원
// -> ArrayList보다 처리속도가 느리고 실행 순서를 보장함
Vector<Integer> vector = new Vector<Integer>();
vector.add(10); //List에서 제공하는 메소드
vector.add(11);
vector.add(12);
vector.add(13);
vector.addElement(14); //이전 Vector 사용 메소드
System.out.println("초기 상태 : " + vector);
System.out.println();
//저장해 놓은 데이터(객체) 가져오기 : get() 메소드 사용
for(int i = 0 ; i <vector.size();i++) {
System.out.println(vector.get(i));
}
System.out.println();
int num = 13;
//indexOf() : 몇 번째 위치에 있는 인덱스 번호를 반환 -> 해당 요소의 인덱스가 없으면 -1을 리턴
int index = vector.indexOf(num);
if(index >= 0) { //index >= 0 요소가 존재함
System.out.println(num + "의 위치 " + index);
} else {
System.out.println(num + "은 존재하지 않음");
}
System.out.println();
num = 14;
int index1 = vector.indexOf(num);
if(vector.contains(num)) {
System.out.println(num + "의 위치 " + index1);
//제거
vector.removeElement(num); //이전 Vector 사용 메소드
System.out.println(num + " 삭제");
}
System.out.println("vector 제거 후 : " + vector);
System.out.println();
//자료 구조의 내부 요소를 순회하는 객체를 생성해서 출력
Iterator<Integer> iterator = vector.iterator();
while(iterator.hasNext()) {
Integer data = iterator.next();
System.out.println(data);
}
}
}
Set
- 순서가 없으며 인덱스도 존재하지 않음
- 중복된 데이터를 가지지 않고 저장 순서를 유지 하지 않음
- 값을 추가하거나 삭제할 경우 추가 혹은 삭제하고자 하는 값이 Set 내부에 있는지 검색한 뒤 수행
- 속도가 List에 비해 느림
- HashSet, TreeSet
- Iterator 사용
Hashing
- 정보를 저장하거나 검색할 때 사용하는 자료 구조
- 많은 데이터를 테이블 형식에 대응 시켜 저장할 수 있도록 만든 데이터 관리 기법
- 데이터를 저장하고 찾을 때 Hash Function을 통해 데이터를 효과적으로 저장하고 가져올 수 있음
- 순차적인 검색이 아니라 key에 해당하는 특정 인덱스값만 알려주면 해당 인덱스에 바로 접근할 수 있음(검색 효율 상승)
package test21;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
class Hash{
//Set 인터페이스 : 순서와 상관없이 중복을 허용하지 않음
//기본적으로 인스턴스 주소가 같으면 동일한 객체임(Hash 함수를 이용한 저장 위치가 같은지 여부)
//아이디가 같아도 같은 회원(객체 내의 저장된 내용(id)가 같은지 여부)
//equals(), hashCode() 메소드 재정의 해서 아이디가 같으면 동일한 회원임을 구현해줘야함
int id;
String name;
//일반 생성자
public Hash(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "(" + this.id + " , " + this.name + ")";
}
//equals(), hashCode()메소드를 재정의해서 논리적으로 같은 객체를 인식할 수 있도록 해주어야함.
@Override
public int hashCode() {
//hashCode() 메소드가 아이디를 반환하도록 재정의
return Objects.hash(id);
}
//매개변수로 반환받은 아이디가 자신의 아이디와 같다면 ture로 반환
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Hash other = (Hash) obj;
return id == other.id;
}
/*
@Override
public boolean equals(Object obj) {
if(obj instanceof Hash) {
Hash hash = (Hash)obj;
if(this.id == hash.id) {
return true;
}else {
return false;
}
}
return false;
}
@Override
public int hashCode() {
System.out.println(System.identityHashCode(id));
//hashCode() 메소드가 회원 아이디를 반환하도록 재정의
return this.id;
}
*/
}
public class HashSetTest1 {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<String>();
hashSet.add("A");
hashSet.add("B");
hashSet.add("C");
hashSet.add("D");
hashSet.add("D"); //중복 허용 X
System.out.println(hashSet);
Set<Hash> set = new HashSet<Hash>();
set.add(new Hash(1,"A"));
set.add(new Hash(2,"B"));
set.add(new Hash(3,"C"));
set.add(new Hash(3,"C"));
System.out.println("Set : " + set);
}
}
728x90
'KDT > Java' 카테고리의 다른 글
240404 Java - 컬렉션 프레임워크 4 (0) | 2024.04.04 |
---|---|
240403 Java - 컬렉션 프레임워크 3 (0) | 2024.04.03 |
240328 Java - 컬렉션 프레임워크 1 (0) | 2024.03.28 |
240327 Java - 제네릭 2 (0) | 2024.03.27 |
240325 Java - 제네릭 1 (0) | 2024.03.25 |