관리 메뉴

HAMA 블로그

스칼라 강좌 (8) - ArrayBuffer 와 Vector 그리고 공변성 본문

Scala

스칼라 강좌 (8) - ArrayBuffer 와 Vector 그리고 공변성

[하마] 이승현 (wowlsh93@gmail.com) 2016. 6. 26. 14:07

ArrayBuffer



각 언어에서 가장 많이 사용되는 컬렉션을 말하자면  (개인적인 경험으로)  C++ 에서는 vector , map 이고 
자바에서는 ArrayList , HashMap   Python 에서는 [] , {}  즉 리스트 와 딕셔너리 였던거 같습니다. 
다른 언어를 사용할때 가장 먼저 찾게되는것이 바로 저런 가장 기본적인 컬렉션들인데요.
스칼라는 무엇일까요?  JVM 상에서 돌아가는 스칼라에도 자바처럼 ArrayList 같은게 있을까요? 

특성

* 스칼라에는 자바의 java.util.ArrayList 가 없다. 대신 ArrayBuffer 가 있다. mutable 속성을 지녔다.

* 자바의 ArrayList 는 C++ 의 vector 와 유사하다. 

  (즉 링크드리스트로 구현되지 않았다. 자바는 LinkedList 가 있고 C++ STL 에서는 list 가 있음)
* ListBuffer 는 링크드 리스트 역할이다.




설명 


http://stackoverflow.com/questions/8287360/scala-equivalent-of-java-util-arraylist  참고



질문 : ArrayList 와 동등한 스칼라의 컬렉션은 무엇인지요? 

 

답변 : ArrayList 는 자바에서 "디폴트" 리스트로 대부분의 사람들이 오용하고 있습니다. 요소들이 추가되고 제거될때 심각한 퍼포먼스 문제가 있는데  Array 의 보충된 컬렉션으로 자연스럽게 사용하고 있습니다. 그래서 제가 이 질문을 보았을때 3가지의 다른 답변을 생각해 보았는데요. 


  • 스칼라의 디폴트 컬렉션은 무엇인가?
  • 어떤 스칼라 컬렉션이 자바의 ArrayList 와 비슷할까?
  • 스칼라에서 Array 에 대체품으로 좋은것은 무엇인가?  


구체적으로 설명해 보자면 


스칼라의 디폴트 컬렉션은 ?

스칼라에서 자바의 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)인가?

  자바가 처음 등장했을때에는 제너릭(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());  // 고양이를 추가??   

  네 먼가 이상해 집니다.

* 왜 공변성은 mutable 한 성질을 지닌 컬렉션에서 위험한가? 

   변경가능한 컬렉션이란 안의 내용을 마구 조작할 수 있다는걸 말한다고 생각해본다면, 안에 있는 요소의 
   타입이 이것도 될 수 있고, 저것도 될 수 있다고 생각하면  먼가 꺼림직하지 않겠습니까? 
   인생이 잘 풀리면 좋겠지만 가끔은 잘못된 객체가 함수안에 들어가서 이상하게 변경 될 수 도 있겠지요.

 * 왜 스칼라 Array 는 자바와 다르게 불변성(invariant)인가?

   스칼라의 Array 는 제너릭으로 동작하기 때문입니다. Array[Int] , Array[String] 처럼 말이죠. 

 * 왜 스칼라 List는 공변성(covariant)인가?

    즉 val arr:Array[Any] = Array[Int](1,2,3) 은 안되는데  val list:List[Any] = List[Int](1,2,3) 은 됩니다.
    하나 예를 들어 보면
     val arr:Array[Int] = Array[Int] (1,2,3) 
     val arr2:Array[Any] = arr
     arr2(0) = 2.54   //  Int 배열에 실수가 들어 갔습니다.!!

     즉  Array 는 mutable 속성이기때문에 문제가 생기지만 List 는 immutable 이기때문에 괜찮은겁니다.   

 

스칼라에서 Array는 자바의 Array와 비슷한데 불변성입니다. 이것은 많은 문제들을 없 앨수 있는데요. 스칼라는 AnyVal (프리미티브와 동등) 을 "제너릭스" 에 대한 타입으로써 받아 드립니다.  모든 Seq 메소드는 Array 에서도 활용 될 수 있게 됩니다. 


Array 와 ArrayBuffer 의 차이 


Array 와  ArrayBuffer 는 둘다 mutable 입니다. 따라서 다음이 가능하죠.


a(i) = 'hello' 


차이점은 

ArrayBuffer 는 사이즈 조정이 자동적이다라는 점입니다.

ArrayBuffer 에 요소를 추가하면 자동적으로 늘어난다는 것이죠


그럼 Array 에 추가를 하면?

새로 만들어진 Array 가 생겨납니다. 예를 들어 보면 


 var array = Array( 1, 2, 3 )  // 배열 생성

 array +:= 4   // 배열 앞에 4 추가한 새로운 배열 생성

 array :+= 0   // 배열 뒤에 4 추가한 새로운 배열 생성

 


ArrayBuffer 예제
val buf = mutable.ArrayBuffer.empty[Int]
buf += 1
buf += 10
val ar = buf.toArray
ar.foreach(println(_))


Vector
http://allaboutscala.com/tutorials/chapter-6-beginner-tutorial-using-scala-immutable-collection/scala-tutorial-learn-use-immutable-vector/


0 Comments
댓글쓰기 폼