컬렉션을 Java에서 ArrayList로 변환

1. 개요

Java 컬렉션을 한 유형에서 다른 유형으로 변환하는 것은 일반적인 프로그래밍 작업입니다. 이 튜토리얼에서는 모든 유형의 컬렉션ArrayList 로 변환합니다 .

튜토리얼 전체에서 우리는 이미 Foo 객체 컬렉션이 있다고 가정 합니다. 거기에서 다양한 접근 방식을 사용하여 ArrayList 를 만듭니다 .

2. 예제 정의

하지만 계속하기 전에 입력과 출력을 모델링 해 보겠습니다.

소스는 모든 유형의 컬렉션이 될 수 있으므로 Collection 인터페이스를 사용하여 선언합니다 .

Collection srcCollection; 

동일한 요소 유형으로 ArrayList 를 생성해야 합니다.

ArrayList newList;

3. ArrayList 생성자 사용

컬렉션을 새 컬렉션에 복사하는 가장 간단한 방법은 생성자를 사용하는 것입니다.

ArrayList에 대한 이전 가이드에서 ArrayList 생성자가 컬렉션 매개 변수를받을 수 있다는 것을 배웠습니다 .

ArrayList newList = new ArrayList(srcCollection);
  • ArrayList 에는 소스 컬렉션에있는 Foo 요소의 단순 복사본이 포함되어 있습니다.
  • 순서는 소스 컬렉션의 순서와 동일합니다.

생성자의 단순성은 대부분의 시나리오에서 훌륭한 옵션이됩니다.

4. Streams API 사용

이제 Streams API를 활용하여 기존 Collection에서 ArrayList를 생성 해 보겠습니다 .

ArrayList newList = srcCollection.stream().collect(toCollection(ArrayList::new));

이 스 니펫에서 :

  • 소스 컬렉션에서 스트림을 가져 와서 collect () 연산자를 적용하여 목록 을 만듭니다.
  • 원하는 목록 유형을 얻기 위해 ArrayList :: new 를 지정합니다.
  • 이 코드는 또한 얕은 복사본을 생성합니다.

정확한 List 유형 에 대해 걱정하지 않았다면 다음을 단순화 할 수 있습니다.

List newList = srcCollection.stream().collect(toList());

참고 toCollection가 ()toList ()가 정적에서 수입 수집기 . 자세한 내용은 Java 8 Collectors에 대한 가이드를 참조하십시오.

5. 딥 카피

"얕은 사본"을 언급하기 전에. 즉, 새 목록의 요소 는 소스 컬렉션에 여전히 존재하는 Foo 인스턴스 와 정확히 동일 합니다. 따라서 참조로 FoonewList 에 복사했습니다 .

두 컬렉션 중 하나에서 Foo 인스턴스 의 내용 을 수정하면 해당 수정 사항이 두 컬렉션 모두에 반영됩니다 . 따라서 다른 컬렉션 수정 하지 않고 두 컬렉션의 요소를 수정하려면 "전체 복사"를 수행해야합니다.

깊은 복사하려면 , 우리는 완전히 새로운 만들 각 요소에 대한 인스턴스를 . 따라서 모든 Foo 필드를 새 인스턴스로 복사해야합니다.

Foo 클래스를 정의 하여 자체적으로 딥 카피하는 방법을 알아 봅시다.

public class Foo { private int id; private String name; private Foo parent; public Foo(int id, String name, Foo parent) { this.id = id; this.name = name; this.parent = parent; } public Foo deepCopy() { return new Foo( this.id, this.name, this.parent != null ? this.parent.deepCopy() : null); } }

여기에서 idname 필드 가 intString 인 것을 볼 수 있습니다 . 이러한 데이터 유형은 값별로 복사됩니다. 따라서 두 가지 모두를 간단히 할당 할 수 있습니다.

부모 필드는 다른 것입니다 클래스입니다. 경우 푸가 돌연변이있어, 주 참조가 이러한 변화에 의해 영향을받을 것이라는 것을 코드. 부모 필드 를 딥 카피해야 합니다 .

이제 ArrayList 변환으로 돌아갈 수 있습니다 . 플로우에 딥 카피를 삽입 하려면 map 연산자 만 있으면 됩니다 .

ArrayList newList = srcCollection.stream() .map(foo -> foo.deepCopy()) .collect(toCollection(ArrayList::new));

다른 컬렉션에 영향을주지 않고 두 컬렉션의 콘텐츠를 수정할 수 있습니다.

전체 복사는 요소의 수와 데이터의 깊이에 따라 긴 프로세스가 될 수 있습니다. 여기에서 병렬 스트림을 사용하면 필요한 경우 성능이 향상 될 수 있습니다.

6. 목록 순서 제어

기본적으로 스트림은 소스 컬렉션에서 발생하는 것과 동일한 순서로 ArrayList 에 요소를 전달합니다 .

이 순서를 변경 하려면 sorted () 연산자를 stream에 적용 할 수 있습니다 . Foo 객체를 이름으로 정렬하려면 :

ArrayList newList = srcCollection.stream() .sorted(Comparator.comparing(Foo::getName)) .collect(toCollection(ArrayList::new));

이 이전 튜토리얼에서 스트림 순서에 대한 자세한 내용을 찾을 수 있습니다.

7. 결론

의 ArrayList의 생성자는의 내용을 얻을 수있는 효과적인 방법입니다 컬렉션을 새로운으로 ArrayList를 .

However, if we need to tweak the resulting list, the Streams API provides a powerful way to modify the process.

The code used in this article can be found in its entirety over on GitHub.