답변 : ArrayList 는 자바에서 "디폴트" 리스트로 대부분의 사람들이 오용하고 있습니다. 요소들이 추가되고 제거될때 심각한 퍼포먼스 문제가 있는데 Array 의 보충된 컬렉션으로 자연스럽게 사용하고 있습니다. 그래서 제가 이 질문을 보았을때 3가지의 다른 답변을 생각해 보았는데요.
- 스칼라의 디폴트 컬렉션은 무엇인가?
- 어떤 스칼라 컬렉션이 자바의 ArrayList 와 비슷할까?
- 스칼라에서 ArrayList 에 대체품으로 좋은것은 무엇인가?
구체적으로 설명해 보자면
스칼라의 디폴트 컬렉션은 ?
스칼라에서 자바의 List 인터페이스와 동등한것은 Seq 입니다. GenSeq 라는 더 제네릭한 인터페이스도 존재하구요. 중요한 차이점은 GenSeq 는 구현에 따라서 직렬 또는 병행 처리하는 연산을 가질 수 있다는 점이에요.
스칼라는 프로그래머에게 Seq 를 팩토리로서 사용할 수 있게 하는데요, 특정 구현을 하도록 강제 하지 않습니다. 그 결과 스칼라의 리스트나 벡터를 선택할 수 있게 되었습니다. 둘 다 변경 불가능 하구요. 벡터는 인덱스 접근시 좋은 성능을 보여줍니다. 리스트도 벡터가 갖지 못한 고유의 장점을 갖고 있죠.
ArrayList 와 비슷한 스칼라의 컬렉션은 무엇인가?
scala.collection.mutable.ArrayBuffer
라고 해야 할거 같습니다. mutable 입니다.
scala.collection.immutable.Vector 도 있다고 해야할 거 같습니다.immutable 입니다.
스칼라에서 Array !!!
글쎄요, 좋은 뉴스는 스칼라에서 그냥 Array 를 사용 할 수 있다는 점입니다. Array 가 자바에서는 제네릭과 일반적으로 호환되지 않기때문에 기피하는 경향이 있습니다. 자바에서 Array 는 co-variance 컬렉션인데 반면 제네릭은 invariant 입니다. 컬렉션이 변경가능한 성질을 지녔을때에 공변성 성질은 프로그램을 위험하게 만들 수 있습니다.
* 공변성 과 불변성
위의 내용은 한번에 이해하기 어려운 내용인데요, 간단히 설명해 보겠습니다.
먼저 다음을 생각해 보세요.
String 이 Object 의 서브타입이라면, String[] 은 Object[] 의 서브타입인가?
String 이 Object 의 서브타입이라면, ArrayList <String> 은 ArrayList<Object> 의 서브타입인가?
즉 어떤 Container[T2] 가 Container[T1] 의 하위 타입이라고 할 수 있는가? 인데요
Container[T2] 은 Container[T1] 의 하위 클래스이다. = 공변성
Container[T2] 은 Container[T1] 과 아무 관계가 없다. = 불변성
* 왜 자바 Array 는 공변성(co-variant)인가? (자바는 따로 Array라는 키워드를 사용하지 않고, 타입[] 방식을 배열(Array)에 사용합니다.)
자바가 처음 등장했을때에는 제네릭(generics) 은 없었습니다. 이때 배열들을 섞거나 비교하는 함수를 만들 때, void doSomthing(Object[] a) 같은거 말이죠. 이 메소드의 매개변수가 만약 불변성으로 다루어 진다면, Object[] 형의 매개 변수만 넣는게 가능할 것 입니다. 하지만 공변성 성질을 가진 덕분에 String[] 도 넣을 수 있게 됬습니다.
따라서 sort 같은 함수도 여러 타입의 매개변수를 넣을 수 있게 되겠지요.
* 왜 자바 제네릭은 불변성(invariant)인가?
List<Dog> 는 List<Animal> 이 아닙니다. 비록 Dog 가 Animal 의 자식타입이라 하더라도 말이죠.
예를들어서
List<Dog> dogs = new List<Dog>(); // 강아지에 대한 리스트를 만듭니다.
List<Animal> a = dogs; // 음.. 부모형을 타입으로 참조를??
a.add(new Cat()); // 역시 Animal의 하위타입인 고양이를 추가??
네 먼가 이상해 집니다.
* 왜 공변성은 mutable 한 성질을 지닌 컬렉션에서 위험한가?
변경가능한 컬렉션이란 안의 내용을 마구 조작할 수 있다는걸 말한다고 생각해본다면, 안에 있는 요소의
타입이 이것도 될 수 있고, 저것도 될 수 있다고 생각하면 먼가 꺼림직하지 않겠습니까?
인생이 잘 풀리면 좋겠지만 가끔은 잘못된 객체가 함수안에 들어가서 이상하게 변경 될 수 도 있겠지요.
* 왜 스칼라 Array 는 자바와 다르게 불변성(invariant)인가?
스칼라에서 Array는 자바의 Array와 비슷한데 불변성입니다. 이것은 많은 문제들을 없앨수 있는데요. 스칼라는 AnyVal (프리미티브와 동등) 을 "제너릭스" 에 대한 타입으로써 받아 드립니다. 모든 Seq 메소드는 Array 에서도 활용 될 수 있게 됩니다.