Iterable / Iterator 인터페이스
- 순회 : 자료 구조에 들어있는 데이터를 차례로 접근해서 처리하는 것
- 각 자료 구조마다 데이터를 접근하는 방법이 모두 다르다.
- Iterator, Iterable 인터페이스 : 자료 구조 구현과 상관 없이 모든 자료 구조를 동일한 방법으로 순회할 수 있는 일관성있는 방법을 제공하는 인터페이스
- Iterable : "반복 가능한"의 의미를 가지고 있다.
- Iterator : "반복자"의 의미를 가지고 있다.
- Iterable 인터페이스 : Iterator 반복자를 반환한다.
- 자료 구조 클래스에서 Iterator로 순회하기 위해서는 그 대상을 Iterable 인터페이스를 구현해야 한다.
Iterable을 구현한 클래스는 Iterator로 순회할 수 있다는 것을 의미한다.
- iterator()를 오버라이딩함으로 Iterator 인터페이스를 구현한 클래스의 객체를 반복자로 반환한다.
- 자료 구조 클래스에서 Iterator로 순회하기 위해서는 그 대상을 Iterable 인터페이스를 구현해야 한다.
- Iterator 인터페이스 : hasNext()로 다음 요소가 있는지 확인하고 next()로 다음 요소를 반환한다.
- 자료 구조에 들어있는 데이터를 순회하기 위해서 Iterator와 Iterable 인터페이스를 모두 구현해줘야 한다.
- 향상된 for문 (for-each문)
- 자료 구조를 순회하는 것이 목적이다.
- Iterable, Iterator 인터페이스를 구현한 객체에 대해서 향상된 for문을 사용할 수 있게 해준다.
//향상된 for문
for(int value : myArray) {
System.out.println(value);
}
//컴파일 시점
while (iterator.hasNext()) {
int value = iterator.next();
System.out.println(value);
}
- 향상된 for문을 사용하면 컴파일 시점에 iterator를 사용한 코드로 변환시켜준다.
- 특정 자료 구조가 Iterable, Iterator를 구현하면 단순히 hasNext(), next() / for-each 문을 사용해서 순회할 수 있다.
- 자료 구조가 아무리 복잡해도 사용하는 입장에서는 동일한 방법으로 매우 쉽게 자료 구조를 순회할 수 있게 해준다. => ★인터페이스가 주는 장점★
- 자바에서 컬렉션 프레임워크를 사용하는 개발자를 위해 편리하고 일관된 방법으로 자료 구조를 순회할 수 있도록 Iterable 인터페이스를 제공하고 Iterator도 다 구현해뒀다.
- 자바의 모든 컬렉션은 Iterable과 Iterator로 순회할 수 있다.
- Map의 경우에는 Key와 Value가 있기 때문에 바로 순회할 수는 없지만 Key 나 Value를 정해서 순회할 수 있다.
- keySet() / values()를 호출함으로 Set / Collection을 반환받아서 순회가 가능하다.
Iterator(반복자) 디자인 패턴 : 객체 지향 프로그래밍에서 컬렉션 요소들을 순회할 때 사용하는 디자인 패턴
컬렉션의 내부 표현 방식을 노출시키지 않으면서 각 요소에 순차적으로 접근할 수 있게 한다.
컬렉션의 구현과는 독립적으로 요소들을 탐색할 수 있는 방법을 제공함으로 코드의 복잡성을 줄이고, 재사용성을 높일 수 있는 디자인 패턴 방식이다.
Comparable / Comparator 인터페이스
- Arrays.sort()
- 배열에 들어있는 데이터를 순서대로 정렬하는 메소드
- 데이터가 적을 때는 듀얼 피벗 퀵소트를 사용하고 데이터가 많을 때는 팀소트 알고리즘을 사용한다.
- Arrays.sort() 인자로 비교자(Comparator 구현체)를 넘겨주면 그 기준에 맞게 정렬할 수 있다.
- 내림차순과 오름차순 각 정렬의 결과 값에 -1을 곱해주면 서로 정렬 결과가 바뀐다.
ex) 내림차순 정렬 결과 값 * -1 => 오름차순
오름차순 정렬 결과 값 * -1 => 내림차순- reversed()를 사용하면 -1을 곱해준 것과 같은 결과가 나온다.
- Comparator.compare()는 두 값을 비교해서 더 작은 값을 앞쪽에 나열하는 오름차순 정렬이 기본이다.
- 두 값을 비교해서 더 작으면 음수, 같으면 0, 더 크면 양수를 반환한다. (오름차순 정렬)
- 내림차순 정렬은 -1을 곱한 것과 같으므로 작으면 양수, 같으면 0, 크면 음수를 반환한다. (내림차순 정렬)
- 내림차순 정렬을 하기 위해서는 오름차순 정렬에 * -1 혹은 reversed() 를 사용한다.
- 두 값을 비교해서 더 작으면 음수, 같으면 0, 더 크면 양수를 반환한다. (오름차순 정렬)
- Integer, String 같은 객체를 제외하고 사용자 정의 타입(User)와 같은 객체를 정렬하기 위해서는 Comparable 인터페이스를 구현함으로 어떤 객체가 더 큰지 비교하는 기능을 정의한다.
- 사용자 정의 타입에 Arrays.sort()를 사용 시 기본 정렬을 시도한다.
- 객체가 스스로 가지고 있는, Comparable 인터페이스를 구현해서 오버라이딩한 compareTo()를 기준으로 정렬한다.
- 기본 정렬 외 정렬 방식을 지정하려면 Comparator를 구현한 클래스를 만들고 compare() 를 오버라이딩 한 후 Arrays.sort() 인자로 구현한 Comparator 객체를 넣어주면 된다.
- 객체의 기본 정렬 방법은 Comparable 인터페이스를 구현해서 정의한다.
- 기본 정렬 외 다른 정렬 방법은 비교자(Comparator)를 별도로 구현해 정렬 메소드에 전달한다.
- Comparator가 Comparable보다 우선권을 갖는다.
- 컬렉션에서 정렬 메소드를 사용하는 방법
- 컬렉션 객체.sort()
- 기본 정렬로 하려면 인자로 null을 넣어준다.
- 기본 정렬 외 다른 정렬을 기준으로 하려면 인자로 Comparator 구현 객체를 넣어줘야한다.
- Collection.sort()
- 컬렉션 객체를 인자로 넣어준다.
- 기본 정렬 외 다른 정렬로 하기 위해서 인자로 Comparator 구현 객체를 넘겨준다.
- 컬렉션 객체.sort()
- Tree 구조는 데이터를 정렬하면서 보관하기 때문에 정렬 기준을 필수로 제공해야 한다.
- 생성자에 별도의 인자가 없으면 기본 정렬로 구현한 Comparable을 사용한다.
- 기본 정렬 외에 다른 정렬을 사용하려면 Tree 객체를 생성할 때부터 생성자에 인자로 Comparator 구현 객체를 넘겨줘야한다.
컬렉션 유틸
//편리한 불변 컬렉션 생성
List<Integer> list = List.of(1, 2, 3);
list.add(1); //예외 발생
//불변 컬렉션 -> 가변 컬렉션으로 변환
ArrayList<Integer> arrList = new ArrayList<>(list);
//가변 컬렉션 -> 불변 컬렉션으로 변환
List<Integer> unmodiList = Collections.unmodifiableList(arrList)
- List.of() / Set.of() / Map.of() : 불변 컬렉션을 생성한다.
- List.of()로 생성한 컬렉션은 불변 객체로 생성이 된다.
그렇기에 만들어진 객체의 데이터를 수정할 수 없는 상태이다. - 일반 Collection 객체가 생성되는 것이 아닌 ImmutableCollection의 객체가 생성된다.
- List.of()로 생성한 컬렉션은 불변 객체로 생성이 된다.
- 불변 컬렉션을 가변 컬렉션으로 변환하려면?
- 가변 컬렉션의 객체의 인자로 넣어서 새로운 가변 컬렉션 객체를 생성한다.
- 반대로 가변 컬렉션을 불변 컬렉션으로 변환하려면?
- Collections.unmodifiable~()의 인자로 가변 컬렉션을 넘기면 불변 컬렉션으로 변환할 수 있다.
- Arrays.asList()
- ~.of()와 같이 불변 컬렉션을 생성하는 메소드다.
- Arrays.asList()로 생성된 리스트는 고정된 크기를 가지고 요소들을 변경할 수 있다.
- add(), remove()는 사용해서 값을 추가, 삭제를 하지 못하지만 set()을 통해 값을 수정할 수는 있다.
- 리스트의 길이는 변경할 수 없다.
- Arrays.asList()로 만들어진 리스트는 불변도, 가변도 아닌 애매한 리스트다.
- ~.of()와 같이 불변 컬렉션을 생성하는 메소드다.
- Arrays.asList() vs List.of()
- List.of()는 불변 컬렉션을 생성하며 리스트를 만들 때 기존 배열에서 각각의 값을 가져와서 새로운 리스트를 구성하는 방식이다.
- Arrays.asList()는 불변도 가변도 아닌 애매한 리스트이며, 기존 배열의 참조 값을 가져오며 값을 수정할 시 원본 배열에도 영향을 미칠 수 있다. 데이터가 엄청 큰 배열을 리스트로 만들 때는 참조 값만 가져오면 되기에 비용을 줄일 수 있다는 장점이 있다.
- List.of()를 사용하는 것을 권장한다.
//빈 불변 컬렉션 생성
List<Integer> list1 = Collections.emptyList();
List<Integer> list2 = List.of();
- 빈 불변 컬렉션을 생성하는 방법
- Collections.empty~()로 생성하기
- ~.of()로 생성하기
Collections.synchronizedList(list)
- Collections.synchronizedList() : 일반 리스트를 멀티스레드 상황에서 동기화 문제가 발생하지 않는 Thread Safe한 리스트로 만들 수 있다.
- 동기화 작업으로 인해 일반 리스트보다 성능은 더 느리다.
출처: [인프런 김영한 실전 자바 - 중급편]
https://www.inflearn.com/course/%EA%B9%80%EC%98%81%ED%95%9C%EC%9D%98-%EC%8B%A4%EC%A0%84-%EC%9E%90%EB%B0%94-%EC%A4%91%EA%B8%89-2/dashboard
김영한의 실전 자바 - 중급 2편 강의 | 김영한 - 인프런
김영한 | 자바 제네릭과 컬렉션 프레임워크를 실무 중심으로 깊이있게 학습합니다. 자료 구조에 대한 기본기도 함께 학습합니다., 국내 개발 분야 누적 수강생 1위, 제대로 만든 김영한의 실전
www.inflearn.com
'Java > [인프런 김영한 실전 자바 - 중급편]' 카테고리의 다른 글
[인프런 김영한 실전 자바 - 중급편] 컬렉션 프레임워크 - Map, Stack, Queue (0) | 2024.07.27 |
---|---|
[인프런 김영한 실전 자바 - 중급편] 컬렉션 프레임워크 - Set (1) | 2024.07.27 |
[인프런 김영한 실전 자바 - 중급편] 컬렉션 프레임워크 - HashSet (2) | 2024.07.26 |
[인프런 김영한 실전 자바 - 중급편] 컬렉션 프레임워크 - Hash (1) | 2024.07.26 |
[인프런 김영한 실전 자바 - 중급편] 컬렉션 프레임워크 - List (0) | 2024.07.26 |