필자는 코딩테스트를 위해 사용할 언어로 자바를 사용하겠다고 결심하였다.
🤔 Why?
1) 자바는 2년 전부터 꾸준히 공부하던 언어다.
2) 파이썬의 숙련도가 낮다.
3) 자바스크립트는 코딩테스트에 활용하기에 불편한 점이 많다. (우선순위 큐 같은 구조는 직접 구현하여 사용해야한다...)
그리하여 오늘은 코딩테스트의 자료구조 문제에 활용하기 위한 Java의 Collection Framework를 보며 활용법을 알아본다.
⚠ 이 글에 나오는 자료구조에 대한 자세한 설명은 자바스크립트를 이용하여 설명한 이전의 글들로 대체한다.
그 전에 코드 테스트를 위해 collection 패키지와 내부에 Member 클래스를 구현한다.
🖥 Member.java
package collection;
public class Member {
private int memberId;
private String memberName;
public Member(int memberId, String memberName) {
this.memberId = memberId; // 멤버의 id
this.memberName = memberName; // 멤버의 이름
}
public int getMemberId() {
return memberId;
}
public void setMemberId(int memberId) {
this.memberId = memberId;
}
public String getMemberName() {
return memberName;
}
public void setMemberName(String memberName) {
this.memberName = memberName;
}
🔷 미리 구현한 자료구조가 담긴 프레임워크로, java.util 패키지에서 제공한다.
주로 쓰이는 것만 모아놓은 대강의 구조는 다음과 같다.
컬렉션 인터페이스 하위에 List 인터페이스와 Set 인터페이스로 나뉜다.
Collection 인터페이스에 선언된 메서드
1) boolean add(E e) : Collection에 객체를 추가한다.
2) void clear() : Collection의 모든 객체를 제거한다.
3) Iterator <E> iterator : Collection을 순환할 반복자를 반환한다.
💡 Iterator
자료 구조 내의 요소를 순회할 때 사용한다. 순서가 없는 Set 인터페이스를 구현하면 get(i) 메서드를 통한 탐색이 불가능하다. 이런 경우를 위한 Iterator의 메서드로 탐색이 가능하다.
4) boolean remove(Object o): Collection에 매개변수에 해당하는 인스턴스가 존재하면 제거한다.
5) int size(): Collection에 있는 요소의 개수를 반환한다.
Map 인터페이스
⚠ 키 값은 고유하며 중복될 수 없지만 value 값은 여러 개이거나 중복될 수 있다.
🖥 활용 코드
package arraylist;
import java.util.*;
import collection.Member;
public class MemberArrayList {
private ArrayList<Member> arrayList;
public MemberArrayList() {
arrayList = new ArrayList<Member>();
}
public void addMember(Member member) {
arrayList.add(member);
}
public void insertMember(Member member, int index) {
arrayList.add(index, member);
}
public boolean removeMember(int memberId) {
// 삭제할 요소가 배열 내에 존재하는지 확인
// 1. 기존의 for 문을 이용한 방법
for(int i = 0; i <arrayList.size(); i++) {
Member member = arrayList.get(i);
int tempId = member.getMemberId();
if(tempId == memberId) {
arrayList.remove(i);
return true;
}
}
// 2. Iterator를 이용한 방법
Iterator<Member> ir = arrayList.iterator();
while(ir.hasNext()) {
Member member = ir.next();
int tempId = member.getMemberId();
if(tempId==memberId) {
arrayList.remove(member);
return true;
}
}
System.out.println(memberId + "가 존재하지 않습니다");
return false;
}
public void showAllMember() {
for(Member member : arrayList) {
System.out.println(member);
}
System.out.println();
}
}
🖥 테스트 코드
package arraylist;
import collection.Member;
public class MemberArrayListTest {
public static void main(String[] args) {
MemberArrayList memberArrayList = new MemberArrayList();
Member memberLee = new Member(1, "이도영");
Member memberPark = new Member(2, "박영규");
Member memberKim = new Member(3, "김청");
Member memberBaek = new Member(4, "백준아");
memberArrayList.addMember(memberLee);
memberArrayList.addMember(memberPark);
memberArrayList.addMember(memberKim);
memberArrayList.addMember(memberBaek);
memberArrayList.showAllMember();
memberArrayList.removeMember(memberPark.getMemberId());
memberArrayList.showAllMember();
memberArrayList.insertMember(memberPark, 0);
memberArrayList.showAllMember();
}
}
🖨 결과
🖥 ArrayList로 구현한 스택
package arraylist;
import java.util.ArrayList;
class MyStack {
private ArrayList<String> arrayStack = new ArrayList<>();
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 StackTest {
public static void main(String[]args) {
MyStack stack = new MyStack();
stack.push("A");
stack.push("B");
stack.push("C");
System.out.println(stack.pop());
System.out.println(stack.pop());
System.out.println(stack.pop());
}
}
🖨 결과
🖥 ArrayList로 구현한 큐
package arraylist;
import java.util.*;
class MyQueue {
private ArrayList<String> arrayQueue = new ArrayList<>();
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 QueueTest {
public static void main(String[] args) {
MyQueue queue = new MyQueue();
queue.enQueue("A");
queue.enQueue("B");
queue.enQueue("C");
System.out.println(queue.dequeue());
System.out.println(queue.dequeue());
System.out.println(queue.dequeue());
}
}
🖨 결과
💡 동기화
2개 이상의 스레드가 동시에 Vector를 사용할 때 오류가 나지 않도록 실행순서를 보장하는 것을 의미한다. 하나의 스레드만 수행되면 단일 스레드라고 하고, 두 개 이상의 스레드가 동시에 실행되는 경우를 멀티 스레드라고 하는데 멀티스레드의 경우 동시에 실행 시 같은 메모리 공간에 접근하기 때문에 변수 값이나 메모리 상태에 오류가 생길 수 있다. 이런 오류를 막을 수 있다는 장점이 있으나 Vector의 모든 메서드는 호출될 때마다 잠금과 해제를 거치기 때문에 ArrayList보다 훨씬 느리다.
🖥 활용 코드
package collection;
import java.util.*;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<String> myList = new LinkedList<>();
myList.add("A");
myList.add("B");
myList.add("C");
System.out.println(myList);
myList.add(1,"D");
System.out.println(myList);
myList.addFirst("E");
System.out.println(myList);
myList.addLast("F");
System.out.println(myList);
System.out.println(myList.removeLast());
System.out.println(myList);
System.out.println(myList.removeFirst());
System.out.println(myList);
}
}
🖨 결과
다음엔 Set 인터페이스와 Map 인터페이스를 알아보자.