본문으로 건너뛰기

Collection

1 Collection

  • 레퍼런스
  • 컬렌션은 객체의 그룹을 나타낸다. 여기서 객체를 요소라고 부른다.
  • 컬렉션은 주로 일반적인 요소의 그룹을 넘겨줄 때 사용된다.
  • 일부 컬렉션 타입은 중복 요소를 허용하는 반면, 다른 일부는 그렇지 않다.
  • 일부 컬렉션 타입은 순서가 있고, 다른 일부는 순서가 없다.
  • Java 플랫폼은 이 인터페이스의 직접적인 구현을 제공하지 않고, Set 및 List와 같은 더 구체적인 하위 인터페이스의 구현을 제공한다.

아래와 같이 컬렉션 구현체들은 Collection 타입의 파라미터가 있는 생성자를 가지고 있다.

public class ArrayList<E> ... {
public ArrayList(Collection<? extends E> c) {}
}
Collection<String> c = ...;
// c의 모든 요소를 가진 새로운 ArrayList를 만들기
List<String> list = new ArrayList<>(c);

1.1 Collection의 계층 구조

Pasted image 20231014123110.png

Collection의 하위 타입

Collction의 하위 타입 아닌 것

2 Collection 메소드

Modifier and TypeMethodDescription
booleanadd(E e)Ensures that this collection contains the specified element (optional operation).
booleanaddAll(Collection<? extends E> c)Adds all of the elements in the specified collection to this collection (optional operation).
voidclear()Removes all of the elements from this collection (optional operation).
booleancontains(Object o)Returns true if this collection contains the specified element.
booleancontainsAll(Collection<?> c)Returns true if this collection contains all of the elements in the specified collection.
booleanequals(Object o)Compares the specified object with this collection for equality.
inthashCode()Returns the hash code value for this collection.
booleanisEmpty()Returns true if this collection contains no elements.
Iterator<E>iterator()Returns an iterator over the elements in this collection.
default Stream<E>parallelStream()Returns a possibly parallel Stream with this collection as its source.
booleanremove(Object o)Removes a single instance of the specified element from this collection, if it is present (optional operation).
booleanremoveAll(Collection<?> c)Removes all of this collection's elements that are also contained in the specified collection (optional operation).
default booleanremoveIf(Predicate<? super E> filter)Removes all of the elements of this collection that satisfy the given predicate.
booleanretainAll(Collection<?> c)Retains only the elements in this collection that are contained in the specified collection (optional operation).
intsize()Returns the number of elements in this collection.
default Spliterator<E>spliterator()Creates a Spliterator over the elements in this collection.
default Stream<E>stream()Returns a sequential Stream with this collection as its source.
Object[]toArray()Returns an array containing all of the elements in this collection.
default <T> T[]toArray(IntFunction<T[]> generator)Returns an array containing all of the elements in this collection, using the provided generator function to allocate the returned array.
<T> T[]toArray(T[] a)Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array.

3 Collection 순차 조회

  • Collection을 순차 조회하는 3가지 방법이 있다.
    • aggregate operation 사용, for-each 사용, Iterator 사용

3.1 Aggregate Operations

  • 자바8 이상부터 선호되는 방식
  • Collection으로 부터 스트림을 얻어 aggregate operation을 수행한다.
  • aggregate operation은 주로 람다식으로 표현됨
  • 즉 스트림을 통해 원소 하나하나에 람다식을 적용한다고 생각할 수 있다.

예시

@Test
void testCollection() {
Shape redShape = new Shape(Color.RED, "red");
Shape greenShape = new Shape(Color.GREEN, "green");
Shape blueShape = new Shape(Color.BLUE, "blue");

Collection<Shape> shapes = Arrays.asList(redShape, greenShape, blueShape);

shapes.stream()
.filter(e -> e.getColor() == Color.RED)
.forEach(e -> System.out.println(e.getName()));
}
red

예시 2

@Test
void testCollection2() {
Shape redShape = new Shape(Color.RED, "red");
Shape greenShape = new Shape(Color.GREEN, "green");
Shape blueShape = new Shape(Color.BLUE, "blue");

Collection<Shape> shapes = Arrays.asList(redShape, greenShape, blueShape);

String result = shapes.stream()
.map(e -> e.getName())
.collect(Collectors.joining(", "));

Assertions.assertThat(result).isEqualTo("red, green, blue");
}

3.2 for-each 사용

  • 향상된 for문 사용 가능

예시

@Test
void testForEach() {
Shape redShape = new Shape(Color.RED, "red");
Shape greenShape = new Shape(Color.GREEN, "green");
Shape blueShape = new Shape(Color.BLUE, "blue");

Collection<Shape> shapes = Arrays.asList(redShape, greenShape, blueShape);

for (Shape shape : shapes) {
System.out.println(shape.getName());
}
}
red
green
blue

3.3 Iterator 사용

  • Iterator는 컬렉션의 원소를 하나씩 조회하거나 삭제할 수 있게 해주는 객체이다.
  • Collection의 iterator()를 호출해 Iterator를 얻을 수 있다.
    • Iterator<Shape> iterator = collection.iterator();

Collection 인터페이스

  • Iterable 인터페이스를 상속받음
package java.util;

public interface Collection<E> extends Iterable<E> {
...
}

Iterable 인터페이스

  • Iterable 인터페이스의 iterator() 메소드를 통해 Iterator를 얻을 수 있다.
public interface Iterable<T> {
Iterator<T> iterator();

default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
}

Iterator 인터페이스

  • remove 메소드는 next 메소드로 조회한 가장 최근 원소를 제거한다.
    • 따라서 next 메소드 실행 후 최대 한번 실행 가능하고 remove 메소드를 두번 연속 실행하면 예외가 발생한다.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}

예시

@Test
void testIterator() {
Shape redShape = new Shape(Color.RED, "red");
Shape greenShape = new Shape(Color.GREEN, "green");
Shape blueShape = new Shape(Color.BLUE, "blue");

Collection<Shape> collection = Arrays.asList(redShape, greenShape, blueShape);
Iterator<Shape> iterator = collection.iterator();

while (iterator.hasNext()) {
Shape shape = iterator.next();
System.out.println(shape.getName());
}
}
red
green
blue

Iterator가 유용한 경우

  • Iterator가 for-each보다 유용한 경우는 바로 필터링이다.
  • for-each 문은 iterator를 숨겼기 때문에 원소를 제거하는 것이 불가능하다
  • 아래의 예시는 특정 조건을 만족하지 못하면 컬렉션에서 원소를 제거하는 코드이다.
static void filter(Collection<?> c) {
for (Iterator<?> it = c.iterator(); it.hasNext(); )
if (!cond(it.next()))
it.remove();
}

참고