이전글 자바 컬렉션의 연장입니다.
1. ArrayList<E>
ArrayList<E>는 가변 크기의 배열을 구현한 컬렉션 클래스로서 경로명은 java.util.ArrayList이며, Vector 클래스와 거의 비슷합니다.
ArrayList의 내부는 배열을 가지고 있으며 ArrayList는 인덱스로 요소를 접근할 수 있습니다. 그리고 인덱스는 0부터 시작합니다.
1-1. ArrayList의 생성
문자열만 다루는 ArrayList를 생성하는 방법은 다음과 같습니다.
ArrayList<String> a = new ArrayList<>();
a는 문자열만 삽입하고 검색할 수 있는 ArrayList객체입니다. 그리고 ArrayList는 스스로 용량을 조절합니다.
1-2. ArrayList의 요소 삽입
add() 메소드를 사용하여 문자열을 삽입할 수 있습니다.
a.add("Hello");
a.add("Hi");
a.add("Java");
a에는 String 타입의 문자열만 삽입이 가능합니다.
ArrayList도 Vector와 마찬가지로 null을 삽입할 수 있습니다.
a.add(null);
add() 메소드를 사용해서 원하는 인덱스에 요소를 삽입할 수 있습니다.
a.add(2, "array");
1-3. ArrayLIst 내의 요소 알아내기
get()이나 elementAt() 메소드를 이용하면 ArrayList 내의 요소를 알아낼 수 있습니다.
String str = a.get(1); // "Hi" 리턴
1-4. ArrayList의 크기 알아내기
size() 메소드를 이용하면 현재 ArrayList에 들어 있는 요소의 개수를 알아낼 수 있습니다.
int len = a.size();
1-5. ArrayList에서 요소 삭제
remove() 메소드를 이용하면 ArrayList 내 임의의 인덱스에 있는 요소를 삭제할 수 있습니다.
a.remove(1);
객체 레퍼런스를 이용해서 remove()를 이용할 수 있습니다.
package practice_java;
import java.util.ArrayList;
public class prac1 {
public static void main(String[] args) {
ArrayList<String> a = new ArrayList<>();
String s = new String("bye");
a.add(s);
a.remove(s);
System.out.println(a);
}
}
결과)
[]
ArrayList의 모든 요소를 삭제하려면 clear() 메소드를 사용하면 됩니다.
a.clear();
2. Iterator
Vector, ArrayList, LinkedList, Set과 같이 요소가 순서대로 저장된 컬렉션에서는 요소를 순차적으로 검색할 때는 java.util 패키지의 Iterator<E> 인터페이스를 사용할 수 있습니다.
<E>는 컬렉션의 매개변수와 동일한 타입을 지정해야 합니다.
Iterator<E>의 메소드는 아래 표와 같습니다.
메소드 | 설명 |
boolean hasNext() | 방문할 요소가 남아 있으면 true리턴 |
E next() | 다음 요소 리턴 |
void remove() | 마지막으로 리턴된 요소 제거 |
아래와 같은 벡터가 있다고 할때
Vector<Integer> v = new Vector<Integer>();
벡터 v의 iterator()를 호출하여, 벡터 v의 각 요소를 순차적으로 검색할 수 있는 Iterator 객체를 반복자라고 부릅니다.
Iterator<Integer> it = v.iterator();
벡터 v의 요소 타입(Integer)에 맞추어 Iterator<E>의 <E>에 Integer를 지정하였습니다.
예시)
package practice_java;
import java.util.*;
public class prac1 {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>();
v.add(5);
v.add(4);
v.add(-1);
v.add(2, 100);
Iterator<Integer> it = v.iterator(); // Iterator 객체 얻기
while (it.hasNext()) { // 방문할 요소가 남아있으면 True리턴
int n = it.next(); // it가 가리키는 요소 리턴
System.out.print(n + " ");
}
System.out.println();
int sum = 0;
it = v.iterator();
while(it.hasNext()) {
int n = it.next();
sum += n;
}
System.out.println("벡터에 있는 정수 합 : " + sum);
}
}
처음 it.next()는 v의 첫 번째 요소를 리턴하고, it는 다음 요소를 가리킨다.
결과)
5 4 100 -1
벡터에 있는 정수 합 : 108
iterator method:
hasNext(): 다음 요소에 읽어올 수 있는 요소가 있는지 없는지 판단, 있으면 true, 없으면 false를 반환(boolean)
(그래서 while문에 next가 아닌 hasNext()를 사용한다.)
next(): 다음 요소를 가져옵니다.
remove(): next()메서드로 읽어온 요소를 삭제합니다.
hasNext() -> next() -> remove() 순서로 호출됩니다.
3. HashMap<K, V>
3-1. HashMap<K, V>
HashMap<K, V> 컬렉션은 경로명이 java.util.HashMap이며, '키(key)'와 '값(value)'의 쌍으로 구성되는 요소를 다룹니다. K는 '키'로 사용할 데이터 타입을 V는 '값'으로 사용할 데이터 타입의 타입매개변수입니다.
해시맵은 내부에 '키'와 '값'을 저장하는 자료 구조를 가지고, 다음과 같이 put(), get() 메소드를 이용하여 요소를 삽입하거나 검색합니다.
package practice_java;
import java.util.*;
public class prac1 {
public static void main(String[] args) {
HashMap<String, String> h = new HashMap<>(); // HashMap클래스로 키:값 문자열 선언, HashMap생성자로 객체 초기화
h.put("apple", "사과");
String kor = h.get("apple");
System.out.println(kor);
}
}
결과)
사과
3-2. 해시맵의 장단점
해시맵은 List<E> 인터페이스를 상속받은 Vector<E>나 ArrayList<E>와는 다르게 요소의 삽입, 삭제 시간이 매우 빠릅니다. 그리고 요소의 검색 시간은 더욱 빠릅니다.
하지만, 해시맵은 인덱스를 이용하여 요소에 접근할 수 없고 오로지 Key를 이용해서만 접근할 수 있습니다.
3-3. 해시맵 생성
해시맵 생성의 기본틀은 다음과 같습니다.
HashMap<String, String> h = new HashMap<>();
3-4. 해시맵에 요소 삽입
요소를 삽일할 때는 put() 메소드에 '키'와 '값'을 입력합니다.
h.put("baby", "아기");
h.put("love", "사랑");
h.put("apple", "사과");
3-5. '키'로 '값' 읽기
get() 메소드에 '키'를 전달하면, '값'을 얻을 수 있습니다.
String kor1 = h.get("love"); // kor1 = "사랑"
만일, 해시맵에 없는 '키'로 get()을 호출하면 null을 리턴합니다.
String kor1 = h.get("babo"); // kor3 = null
3-6. '키'로 요소 삭제
'키'를 이용하여 요소를 삭제할 때 다음과 같이 remove() 메소드를 이용합니다.
h.remove("apple"); // apple 삭제
3-7. 요소 개수 알아내기
요소의 개수는 size() 메소드를 사용하여 알아낼 수 있습니다.
int n = h.size();
*해시맵은 배열이나 컬렉션 클래스의 벡터, ArrayList와 다르게 삽입된 순서로 저장되지 않습니다.
4. LinkedList<E>
LinkedList<E>는 List<E> 인터페이스를 구현한 클래스로서 경로명이 java.util.LinkedList입니다. LinkedList는 Vector, ArrayList와 다르게 노드를 양방향으로 연결하여 저장합니다.
5. Collections 클래스 활용
java.util 패키지에 포함된 Collections 클래스는 다음과 같이 컬렉션을 다루는 유용한 여러 메소드를 지원합니다.
- sort() : 컬렉션에 포함된 요소들의 정렬
- reverse() : 요소를 반대 순으로 정렬
- max(), min() : 요소들의 최댓값과 최솟값 찾아내기
- binarySearch() : 이진 검색
위의 메소드는 모두 static타입이기 때문에 Collections 객체를 생성할 필요는 없습니다.
package practice_java;
import java.util.*;
public class prac1 {
public static void main(String[] args) {
Vector<String> myList = new Vector<>();
myList.add("트랜스포머");
myList.add("스타워즈");
myList.add("매트릭스");
myList.add(0, "터미네이터");
myList.add(2, "아바타");
Collections.sort(myList); // 요소 정렬
System.out.println(myList);
Collections.reverse(myList); // 요소 역순 정렬
System.out.println(myList);
int index = Collections.binarySearch(myList, "아바타") + 1;
System.out.println("아바타는 " + index + "번째 요소입니다.");
}
}
결과)
[매트릭스, 스타워즈, 아바타, 터미네이터, 트랜스포머]
[트랜스포머, 터미네이터, 아바타, 스타워즈, 매트릭스]
아바타는 3번째 요소입니다.
6. 제네릭 클래스
제네릭 클래스를 작성하는 방법은 기존의 클래스 작성 방법과 유사합니다. 클래스 이름 다음에 일반화된 타입(generic type)의 매개변수를 <와 > 사이에 추가한다는 차이가 있습니다.
6-1. 제네릭 클래스 작성
public class MyClass<T> { // 제네릭 클래스 MyClass, 타입 매개변수 T
T val; // 변수 val의 타입은 T
void set(T a) {
val = a; // T 타입의 값 a를 val에 지정
}
T get() {
return val; // T 타입의 값 val 리턴
}
}
6-2. 제네릭 클래스에 대한 레퍼런스 변수 선언
제네릭 클래스의 레퍼런스 변수를 선언할 때 구체적인 타입을 적어야 합니다.
MyClass<String> s; // <T>를 String으로 구체화
List<Integer> li; // <E>를 Integer로 구체화
Vector<String> vs; // <E>를 String으로 구체화
6-3. 제네릭 객체 생성 - 구체화(specialization)
제네릭 클래스에 구체적인 타입을 대입하여 구체적인 객체를 생성하는 과정을 "구체화"라고 부르며 자바 컴파일러에 의해 이루어집니다
package practice_java;
class MyClass<T> { // 제네릭 클래스 MyClass, 타입 매개변수 T
T val; // 변수 val의 타입은 T
void set(T a) {
val = a; // T 타입의 값 a를 val에 지정
}
T get() {
return val; // T 타입의 값 val 리턴
}
}
public class prac1 {
public static void main(String[] args) {
MyClass<String> s = new MyClass<String>();
s.set("hello");
System.out.println(s.get());
MyClass<Integer> n = new MyClass<>();
n.set(5);
System.out.println(n.get());
}
}
결과)
hello
5
MyClass<String>은 String만 다루는 구체적인 클래스가 되며, MyClass<Integer>는 정수만 다루는 구체적인 클래스가 됩니다.
구체화된 MyClass<String>코드는 아래와 같습니다.
class MyClass<Sting> { // 구체화된 제네릭 클래스 MyClass
String val; // 변수 val의 타입은 String
void set(String a) {
val = a; // String 타입의 값 a를 val에 지정
}
String get() {
return val; // String 타입의 값 문자열 val 리턴
}
}
제네릭의 구체화에 원시 타입(primitive type)은 사용할 수 없습니다.
(int, double, char등의 기본 타입)
6-4. 타입 매개변수
제네릭 클래스 내에서 제네릭 타입을 가진 객체의 생성은 허용되지 않습니다.
class MyVector<E> {
E create() {
E a = new E(); // 제네릭 타입의 객체 생성 불가
return a;
}
}
6-5. 제네릭과 배열
제네릭에서는 배열에 대한 제한을 두고 있습니다. 제네릭 클래스 또는 인터페이스 타입의 배열은 선언할 수 없습니다.
GStack<Integer> gs = new Gstack<>[10]; // 컴파일 오류
6-6. 제네릭 메소드
클래스의 일부 메소드만 제네릭으로 구현할 수 있습니다.
class GenericMethodEx {
static <T> void toStack(T[] a, GStack<T> gs) {
for (int i = 0; i < a.length; i++) {
gs.push(a[i]);
}
}
}
'[WEB] > [Java]' 카테고리의 다른 글
[Java] 자바 static의 의미와 사용방법 (0) | 2022.09.29 |
---|---|
[Java] 윈도우 자바 환경변수 설정방법 (0) | 2022.09.29 |
[Java] 자바 컬렉션 (0) | 2022.09.24 |
[Java] 자바 제네릭 클래스, 제네릭 메소드 (0) | 2022.09.24 |
[Java] Object 클래스 (0) | 2022.09.23 |