Programming in Sala 책으로 스칼라 스터디하면서 정리했던 내용이다. 지금은 3판 번역본도 나왔지만, 약간 앞서서 스터디를 시작해서 2판으로 진행했다.

17장

시퀀스

리스트 List

  • 앞부분에 빠르게 원소를 삭제하거나 추가할 수 있다. -> 패턴 매치 이점
  • 불변 객체
  • 임의 위치 접근 시에는 빠르지 않다.
val colors = List("red","blue","green")
colors.head     // red
colors.tail     // List("blue","green")

배열 Array

  • 임의 위치 효율적으로 접근
val fiveInts = new Array[Int](5)
val fiveToOne = Array(5, 4, 3, 2, 1)

fiveInts(0) = fiveToOne(4)

리스트 버퍼 ListBuffer

  • 가변 객체
  • 앞뒤로 원소를 추가하는 데 상수시간 소요
  • += : 원소를 리스트 뒤에 추가
  • +=: : 원소를 리스트 앞에 추가
import scala.collection.mutable.ListBuffer
val buf = new ListBuffer[Int]
buf += 1        // ListBuffer(1)
buf += 2        // ListBuffer(1,2)
3 +=: buf       // ListBuffer(3,1,2)
buf.toList      // List(3,1,2)

배열 버퍼 ArrayBuffer

  • 앞뒤로 원소를 추가/삭제 가능
  • 모든 배열 연산 사용 가능
  • 추가/삭제에 평균적으로 상수시간 걸리나 종종 선형 시간 필요
import scala.collection.mutable.ArrayBuffer
val buf = new ArrayBuffer[Int]()
buf += 12       // ArrayBuffer(12)
buf += 15       // ArrayBuffer(12,15)
buf.length      // 2
buf(0)          // 12

문자열 StringOps

  • StringStringOps로 암시적 변환하여 시퀀스처럼 문자열을 다룰 수 있다.
def hasUpperCase(s: String) = s.exists(_.isUpper)

집합 Set

  • 한 파일 안에서 가변/불변 집합을 다 사용하는 방법
import scala.collection.mutable
val mutaSet = mutable.Set(1,2,3)
  • 특정 객체는 최대 하나만 들어감. 동일한지는 ==로 비교
// 다른 단어 갯수 세기
val text = "See Spot run. Run, Spot. Run!"
val wordsArray = text.split("[ !,.]+")
val words = mutable.Set.empty[String]

for (word <- wordsArray) words += word.toLowerCase
words       // Set(spot, run, see)

집합 연산

  • val nums = Set(1,2,3) : 불변 집합 생성
  • nums + 5 : 원소를 추가
  • nums - 3 : 원소를 제거
  • nums ++ List(5,6) : 여러 원소 추가
  • nums -- List(1,2) : 여러 원소 제거
  • nums & Set(1,3,5,7) : 두 집합의 교집합
  • nums.size : 집합의 크기
  • nums.contains(3) : 집합에 원소가 있는지 확인
  • import scala.collection.mutable : 가변 컬렉션 접근
  • val words = mutable.Set.empty[String] : 빈 문자열 집합 생성
  • words += "the" : 원소 추가
  • words -= "the" : 원소 제거
  • words ++= List("do","re","mi") : 여러 원소 추가
  • `words --= List("do","re") : 여러 원소 제거
  • words.clear : 모든 원소 제거

맵 Map

def countWords(text: String) = {
  val counts = mutable.Map.empty[String, Int]
  for (rawWord <- text.split("[ ,!.]+")) {
    val word = rawWord.toLowerCase
    val oldCount =
      if (counts.contains(word))
        counts(word)
      else
        0
    counts += (word -> (oldCount + 1))
  }
  counts
}

맵 연산

  • val nums = Map("i" -> 1, "ii" -> 2) : 불변 맵 생성
  • nums + ("v" -> 6) : 원소 추가
  • nums - "ii" : 원소 제거
  • nums ++ List("iii"->3, "v"->5) : 여러 원소 추가
  • nums -- List("i", "ii") : 여러 원소 제거
  • nums.size : 맵 크기
  • nums.contains("ii") : 키 포함 여부
  • nums("ii") : 키에 해당하는 값
  • nums.keys : 모든 키의 iterable
  • nums.keySet : 모든 키의 Set
  • nums.values : 모든 값의 iterable
  • nums.isEmpty : 맵이 비었는지 검사
  • import scala.collection.mutable : 가변 컬렉션 접근
  • val words = mutable.Map.empty[String,Int] : 가변 맵 생성
  • words += ("one" -> 1) : 원소 추가
  • words -= "one" : 원소 제거
  • words ++= List("one" -> "two" -> 2, "three" -> 3) : 여러 원소 추가
  • words --= List("one", "two") : 여러 원소 제거

디폴트 집합/맵

가변 집합/맵

  • scala.collection.mutable.Set() -> scala.collection.mutable.HashSet
  • scala.collection.mutable.Map() -> scala.collection.mutable.HashMap

불변 집합/맵

  • 5개 이상 : 해시 사용하는 구현
  • 5개 이하 : 특별한 클래스
    • 0 : scala.collection.immutable.EmptySet / ... .EmptySet
    • 1 ~ 4 : scala.collection.immutable.Set1 / ... .Map1 ~ scala.collection.immutable.Set4 / / ... .Map4

정렬된 집합/맵

  • SortedSet / SortedMap 트레이트
  • TreeSet / TreeMap 클래스 : red-black tree 사용. Ordered 트레이트를 따라 순서 결정
// TreeSet
import scala.collection.immutable.TreeSet
val ts = TreeSet(9,3,1,8,0,2,7,4,6,5)   // TreeSet(0,1,2,3,4,5,6,7,8,9)
val cs = TreeSet('f','u','n')           // TreeSet(f,n,u)

// TreeMap
import scala.collection.immutable.TreeMap
val tm = TreeMap(3 -> 'x', 1 -> 'x', 4 -> 'x')  // Map(1 -> x, 3 -> x, 4 -> x)
tm += (2 -> 'x')
tm                                              // Map(1 -> x, 2 -> x, 3 -> x, 4 -> x)

가변/불변 컬렉션

  • 크키가 작은 맵/집합의 경우 불변인 경우 공간을 적게 차지함.
  • 불변 컬렉션의 지원하지 않는 a += b 연산자는 a = a + b로 표현식을 해석함.(=로 끝나는 모든 연산)
var people = Set("Nancy", "Jane")
people += "Bob"

컬렉션 초기화

  • 동반 객체 이름 뒤의 괄호 안에 모든 원소. -> apply 메소드 호출로 변환하여 처리함.
List(1,2,3)
Set('a','b','c')
  • 타입 추론이 정확하지 않을때에는 타입을 지정.
val stuff = mutable.Set[Any](42)
  • 리스트로 집합/맵 만들때는 ++ 연산자 활용
val colors = List("blue","yellow","red","green")
val treeSet = TreeSet[String]() ++ colors
  • 리스트/배열로 변환
    • iterator 호출했을때의 원소 순서
    • 모든 원소를 복사하기 때문에 느릴 수 있음
// 리스트
treeSet.toList

// 배열
treeSet.toArray
  • 가변/불변 변환 : ++ 연산자 활용
import scala.collection.mutable

val treeSet = TreeSet("blue","yellow","red","green")
val mutaSet = mutable.Set.empty ++= treeSet
val immutaSet = Set.empty ++ mutaSet

튜플

  • 원소의 타입이 서로 다를 수 있음
  • 메소드에서 여러값 반환이 일반적 용도
def longestWord(words: Array[String]) = {
  var word = words(0)
  var idx = 0
  for (i <- 1 until words.length)
    if (words(i).length > word.length) {
      word = words(i)
      idx = i
    }
  (word, idx)
}
  • 결합에 어떤 의미가 있는 경우, 결합에 메소드를 추가하기 원한다면 클래스 사용
  • _1, _2, ... 으로 원소 접근


+ Recent posts