Iterable 인터페이스
자바에서 Iterable 인터페이스는 컬렉션 객체를 순회(반복)할 수 있는 기능을 제공합니다. 이 인터페이스는 java.util 패키지에 포함되어 있으며, Iterator를 반환하는 iterator() 메서드를 정의하고 있습니다. 모든 컬렉션 클래스(예: List, Set, Queue)는 Iterable 인터페이스를 구현합니다.
Iterable 인터페이스 정의
Iterable 인터페이스는 다음과 같이 정의됩니다:
package java.lang;
import java.util.Iterator;
public interface Iterable<T> {
Iterator<T> iterator();
}
주요 메서드
- iterator(): 컬렉션을 순회할 때 사용할 Iterator를 반환합니다.
예제 코드
Iterable 인터페이스를 구현하는 클래스와 이를 사용하는 예제를 보겠습니다.
커스텀 클래스에서 Iterable 구현
먼저, Iterable 인터페이스를 구현하는 커스텀 클래스를 작성해보겠습니다.
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyIterableCollection<T> implements Iterable<T> {
private T[] items;
private int size;
public MyIterableCollection(T[] items) {
this.items = items;
this.size = items.length;
}
@Override
public Iterator<T> iterator() {
return new MyIterator();
}
private class MyIterator implements Iterator<T> {
private int currentIndex = 0;
@Override
public boolean hasNext() {
return currentIndex < size;
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return items[currentIndex++];
}
}
public static void main(String[] args) {
String[] items = {"Apple", "Banana", "Cherry"};
MyIterableCollection<String> collection = new MyIterableCollection<>(items);
for (String item : collection) {
System.out.println(item);
}
}
}
설명
- MyIterableCollection 클래스:
- 제네릭 클래스이며 Iterable<T> 인터페이스를 구현합니다.
- items 배열과 size 변수를 사용하여 컬렉션의 요소와 크기를 저장합니다.
- iterator() 메서드를 오버라이드하여 커스텀 Iterator를 반환합니다.
- MyIterator 클래스:
- Iterator<T> 인터페이스를 구현하는 내부 클래스입니다.
- hasNext() 메서드는 컬렉션에 다음 요소가 있는지 확인합니다.
- next() 메서드는 현재 요소를 반환하고, 인덱스를 다음으로 이동합니다. 더 이상 요소가 없으면 NoSuchElementException을 던집니다.
- main 메서드:
- MyIterableCollection 객체를 생성하고, 문자열 배열을 전달합니다.
- for-each 루프를 사용하여 컬렉션의 요소를 순회합니다. 이는 내부적으로 iterator() 메서드를 호출하여 Iterator를 사용하게 됩니다.
copyOf 메서드
copyOf 메서드는 Java의 java.util.Arrays 클래스에서 제공하는 메서드로, 배열을 복사하는 데 사용됩니다. 이 메서드는 주어진 배열의 원소를 새로운 배열로 복사하고, 필요에 따라 배열의 크기를 조정할 수도 있습니다. copyOf메서드는 기본적으로 두 가지 형태로 제공됩니다:
- copyOf(original, newLength): 주어진 배열의 원소를 새로운 배열로 복사하고, 새로운 배열의 길이를 지정합니다.
- copyOf(original, newLength, newType): 주어진 배열의 원소를 새로운 배열로 복사하고, 새로운 배열의 길이와 타입을 지정합니다.
다음은 copyOf 메서드를 사용하는 예제입니다.
package com.example.copyofexample;
import java.util.Arrays;
public class ArrayCopyExample {
public static void main(String[] args) {
// 원본 배열 생성
int[] originalArray = {1, 2, 3, 4, 5};
// copyOf를 사용하여 원본 배열을 복사하고 길이를 7로 지정
int[] copiedArray = Arrays.copyOf(originalArray, 7);
// 결과 출력
System.out.println("원본 배열: " + Arrays.toString(originalArray));
System.out.println("복사된 배열: " + Arrays.toString(copiedArray));
}
}
원본 배열: [1, 2, 3, 4, 5]
복사된 배열: [1, 2, 3, 4, 5, 0, 0]
이 예제에서는 originalArray라는 원본 배열을 생성하고, Arrays.copyOf 메서드를 사용하여 길이가 7인 새로운 배열 copiedArray를 생성합니다. 원본 배열의 길이가 5이므로, 추가된 두 개의 요소는 기본값인 0으로 채워집니다.
copyOf 메서드를 사용하여 배열을 복사할 때, 새 배열의 길이가 원본 배열보다 길면 기본값으로 채워지고, 짧으면 잘라집니다. 이 메서드는 배열을 쉽게 복사하고 크기를 조정할 수 있어 유용합니다.
키-값 쌍 (Key-Value Pair)
키-값 쌍(Key-Value Pair)은 데이터를 저장하고 검색하는 데 사용되는 기본적인 데이터 구조 중 하나입니다. 이 구조에서는 각 데이터 항목이 고유한 키와 그에 대응하는 값으로 구성됩니다. 키는 값을 식별하는 데 사용되며, 각 키는 고유해야 합니다. 값은 키에 연결된 데이터입니다.
주요 개념
- 키 (Key): 데이터를 식별하는 데 사용되는 고유한 식별자입니다. 키는 중복될 수 없습니다.
- 값 (Value): 키에 연관된 데이터입니다. 값은 중복될 수 있습니다.
자바에서의 키-값 쌍
자바에서는 Map 인터페이스와 이를 구현한 클래스들을 사용하여 키-값 쌍을 저장하고 관리합니다. 대표적인 구현체로는 HashMap, TreeMap, LinkedHashMap 등이 있습니다.
예제: HashMap 사용
HashMap은 가장 많이 사용되는 키-값 쌍을 저장하는 데이터 구조 중 하나입니다.
import java.util.HashMap;
import java.util.Map;
public class KeyValueExample {
public static void main(String[] args) {
// HashMap 생성
Map<String, Integer> map = new HashMap<>();
// 키-값 쌍 추가
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Cherry", 3);
// 키를 사용하여 값 검색
int value = map.get("Apple");
System.out.println("Value for key 'Apple': " + value); // 출력: Value for key 'Apple': 1
// 모든 키-값 쌍 출력
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
// 키-값 쌍 존재 여부 확인
boolean containsKey = map.containsKey("Banana");
System.out.println("Contains key 'Banana': " + containsKey); // 출력: Contains key 'Banana': true
// 키-값 쌍 제거
map.remove("Cherry");
// 모든 키-값 쌍 출력
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
}
}
Value for key 'Apple': 1
Key: Apple, Value: 1
Key: Banana, Value: 2
Key: Cherry, Value: 3
Contains key 'Banana': true
Key: Apple, Value: 1
Key: Banana, Value: 2
설명
- HashMap 생성:
- Map<String, Integer> map = new HashMap<>();는 키가 String이고 값이 Integer인 HashMap을 생성합니다.
- 키-값 쌍 추가:
- map.put("Apple", 1);와 같은 메서드를 사용하여 키-값 쌍을 추가합니다. 여기서 "Apple"은 키, 1은 값입니다.
- 키를 사용하여 값 검색:
- map.get("Apple");을 통해 키 "Apple"에 대응하는 값을 검색할 수 있습니다.
- 모든 키-값 쌍 출력:
- map.entrySet()을 사용하여 for-each 루프를 통해 모든 키-값 쌍을 출력할 수 있습니다.
- 키-값 쌍 존재 여부 확인:
- map.containsKey("Banana");는 맵에 "Banana" 키가 있는지 확인합니다.
- 키-값 쌍 제거:
- map.remove("Cherry");는 "Cherry" 키와 그에 대응하는 값을 제거합니다.
키-값 쌍의 응용
키-값 쌍은 다양한 응용 분야에서 사용됩니다. 예를 들어:
- 캐시: 키-값 쌍을 사용하여 데이터를 캐싱합니다.
- 설정 저장: 애플리케이션 설정을 키-값 쌍으로 저장하고 관리합니다.
- 데이터베이스: NoSQL 데이터베이스(예: MongoDB, Redis)는 키-값 저장소를 기반으로 합니다.
- 인덱싱: 키-값 쌍을 사용하여 데이터베이스 테이블의 인덱스를 관리합니다.
키-값 쌍은 효율적이고 직관적인 데이터 저장 및 검색 방법을 제공하므로 다양한 프로그래밍 문제에서 널리 사용됩니다.
향상된 for 문 (for-each 구조)
for-each 구조의 기본 구문은 다음과 같습니다:
for (ElementType element : collection) {
// 요소에 대한 작업 수행
}
여기서 ElementType은 컬렉션 또는 배열의 요소 타입이고, element는 각 반복에서 현재 요소를 참조하는 변수입니다. collection은 배열이나 Iterable 인터페이스를 구현한 컬렉션입니다.
배열을 순회하는 for-each 예제
public class ForEachArrayExample {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
}
}
1
2
3
4
5
컬렉션을 순회하는 for-each 예제
import java.util.ArrayList;
import java.util.List;
public class ForEachCollectionExample {
public static void main(String[] args) {
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Cherry");
for (String fruit : fruits) {
System.out.println(fruit);
}
}
}
Apple
Banana
Cherry
주요 특징
- 간결성:
- for-each 구조는 코드가 간결하고 가독성이 좋습니다.
- 반복자(Iterator)나 인덱스를 직접 사용하지 않으므로 코드가 단순해집니다.
- 안전성:
- for-each 구조는 인덱스 범위 초과와 같은 오류를 방지할 수 있습니다.
- 컬렉션의 크기나 배열의 길이에 대해 신경 쓸 필요가 없습니다.
- 불변성:
- for-each 구조는 컬렉션의 요소를 수정할 수 없습니다. 컬렉션이나 배열의 요소를 수정하려면 반복자(Iterator)를 사용해야 합니다.
제한사항
- 수정 불가: for-each 구조는 컬렉션의 요소를 삭제하거나 수정할 수 없습니다. 요소를 삭제하거나 수정하려면 반복자(Iterator) 또는 인덱스를 사용하는 전통적인 for 문을 사용해야 합니다.
- 역순 반복 불가: for-each 구조는 요소를 역순으로 반복할 수 없습니다. 역순 반복이 필요하면 인덱스를 사용하는 전통적인 for 문을 사용해야 합니다.
- 반복 제어 불가: for-each 구조는 반복 중간에 루프를 제어하기 어렵습니다. 반복을 중간에 종료하거나 건너뛰려면 break 또는 continue를 사용할 수 있습니다.
Iterator
자바에서 Iterator는 컬렉션의 요소를 하나씩 순회(iterate)하며 접근할 수 있는 인터페이스입니다. Iterator 인터페이스는 자바 컬렉션 프레임워크의 일부로, 컬렉션의 요소를 순회하고 수정할 수 있는 표준 방법을 제공합니다.
주요 메서드
Iterator 인터페이스는 다음과 같은 세 가지 주요 메서드를 제공합니다:
- boolean hasNext( ): 컬렉션에 순회할 요소가 더 있는지를 확인합니다.
- E next( ): 다음 요소를 반환하고, 순회 상태를 다음 요소로 이동시킵니다.
- void remove( ): Iterator가 마지막으로 반환한 요소를 컬렉션에서 제거합니다. 이 메서드는 선택적이며, 모든 Iterator 구현체에서 반드시 지원되는 것은 아닙니다.
기본적인 Iterator 사용 예제
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// Iterator 생성
Iterator<String> iterator = list.iterator();
// Iterator를 사용한 순회
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}
}
}
Apple
Banana
Cherry
요소 제거 예제
Iterator의 remove() 메서드를 사용하여 컬렉션에서 요소를 제거할 수도 있습니다.
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class IteratorRemoveExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
if (fruit.equals("Banana")) {
iterator.remove();
}
}
// 요소 제거 후 리스트 출력
for (String fruit : list) {
System.out.println(fruit);
}
}
}
- next( ) 메서드로 가져온 요소가 "Banana"와 같으면, remove( ) 메서드를 사용하여 해당 요소를 제거합니다.
- Iterator의 remove( ) 메서드를 사용하면, 반복문 도중에 안전하게 요소를 제거할 수 있습니다.
Apple
Cherry
Iterator를 사용하면 컬렉션의 요소를 반복적으로 처리할 수 있으며, 특히 요소를 제거하는 경우 안전하고 일관된 방법을 제공합니다.
toArray 메서드
toArray 메서드는 컬렉션(Collection) 인터페이스에 정의되어 있으며, 컬렉션의 요소를 배열로 변환할 때 사용됩니다. 이는 특히 컬렉션의 요소를 배열 기반 API에 전달해야 하거나, 컬렉션의 요소를 배열로 처리해야 할 때 유용합니다.
주요 용도
- 배열 기반 API와의 호환성: 기존의 배열 기반 API에 컬렉션의 데이터를 전달해야 할 때.
- 배열의 고정 크기 요구: 컬렉션의 요소를 고정 크기의 배열로 처리해야 할 때.
- 간편한 데이터 변환: 컬렉션의 요소를 배열로 변환하여 다양한 배열 연산을 수행할 때.
toArray 메서드의 사용 예
toArray 메서드는 두 가지 형태로 제공됩니다:
- Object[] toArray(): 컬렉션의 요소를 Object 배열로 반환합니다.
- <T> T[] toArray(T[] a): 지정된 타입의 배열로 컬렉션의 요소를 반환합니다.
예제 1: Object[] toArray()
import java.util.ArrayList;
import java.util.List;
public class ToArrayExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// Object 배열로 변환
Object[] array = list.toArray();
// 배열 요소 출력
for (Object obj : array) {
System.out.println(obj);
}
}
}
예제 2: <T> T[] toArray(T[] a)
import java.util.ArrayList;
import java.util.List;
public class ToArrayExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// String 배열로 변환
String[] array = list.toArray(new String[0]);
// 배열 요소 출력
for (String str : array) {
System.out.println(str);
}
}
}
예제 3: toArray(T[] a)의 동작 방식
import java.util.ArrayList;
import java.util.List;
public class ToArrayExample {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Apple");
list.add("Banana");
list.add("Cherry");
// 배열 크기가 컬렉션 크기보다 작은 경우
String[] smallArray = list.toArray(new String[1]);
System.out.println("Small Array: ");
for (String str : smallArray) {
System.out.println(str);
}
// 배열 크기가 컬렉션 크기와 같은 경우
String[] exactArray = list.toArray(new String[list.size()]);
System.out.println("Exact Array: ");
for (String str : exactArray) {
System.out.println(str);
}
// 배열 크기가 컬렉션 크기보다 큰 경우
String[] largeArray = list.toArray(new String[5]);
System.out.println("Large Array: ");
for (String str : largeArray) {
System.out.println(str);
}
}
}
toArray(T[] a) 메서드의 동작 방식
- 배열 크기가 컬렉션 크기보다 작은 경우: 새로운 배열이 생성되고 컬렉션의 요소로 채워집니다.
- 배열 크기가 컬렉션 크기와 같은 경우: 지정된 배열이 컬렉션의 요소로 채워집니다.
- 배열 크기가 컬렉션 크기보다 큰 경우: 지정된 배열이 컬렉션의 요소로 채워지고, 남는 부분은 null로 설정됩니다.
Small Array:
Apple
Banana
Cherry
Exact Array:
Apple
Banana
Cherry
Large Array:
Apple
Banana
Cherry
null
null
요약
toArray 언제 쓰냐 -> 컬렉션의 요소를 배열로 변환할 때 사용
- toArray 메서드는 컬렉션의 요소를 배열로 변환하는 데 사용됩니다.
- Object[] toArray() 메서드는 컬렉션의 요소를 Object 배열로 반환합니다.
- <T> T[] toArray(T[] a) 메서드는 지정된 타입의 배열로 컬렉션의 요소를 반환합니다.
- 배열 기반 API와의 호환성을 위해, 고정 크기의 배열이 필요할 때, 또는 컬렉션의 요소를 배열로 처리해야 할 때 유용하게 사용됩니다.
'Study Memo' 카테고리의 다른 글
2024.07.22 (월) { 예외처리, try-catch } (0) | 2024.07.22 |
---|---|
2024.07.19 (금) { 얕은&깊은복사 , 컬렉션구현방식, sublist - view (부분집합) } (0) | 2024.07.19 |
2024.07.17 (수) { raw type, Arrays.asList, 자바에 2가지의 경고 "unchecked", "varargs" } (0) | 2024.07.17 |
2024.07.16 (화) { valueOf, 직렬화(Serialize), is-a, 마커인터페이스 } (0) | 2024.07.16 |
2024.07.15 (월) { 제너릭 } (0) | 2024.07.15 |