पाठ 5 / 25
Immutable Collections
Choose and use List, Vector, Map and Set with their transformation methods.
A rich, immutable-first library
Scala's collections are immutable by default: operations return new collections and leave the original unchanged, which makes code easier to reason about and safe to share between threads. The main types are List (a singly linked list: fast prepend with :: and head/tail access, slow indexed access), Vector (fast indexed access and updates, a good default sequence), Map (key-value pairs, created with "pune" -> 2), Set (unique elements), Range (1 to 10, 0 until n) and Array (a mutable Java array). Mutable versions live in scala.collection.mutable (such as ArrayBuffer and mutable.Map) for local, performance-sensitive code. All share a large API: map, filter, flatMap, foldLeft, reduce, sum, groupBy, groupMapReduce, partition, sortBy, zip, collect (filter and map with a partial function), find, exists, forall, take, drop, sliding and distinct. .view creates lazy views that avoid intermediate collections, and LazyList handles potentially infinite sequences.
Collection operations on orders
Grouping, folding and collecting without mutation.
case class Order(id: String, city: String, totalPaise: Long, paid: Boolean)
val orders = Vector(
Order("o1", "Pune", 120000, paid = true),
Order("o2", "Delhi", 30000, paid = false),
Order("o3", "Pune", 80000, paid = true)
)
val revenue = orders.filter(_.paid).map(_.totalPaise).sum // 200000
val byCity = orders.groupBy(_.city) // Map[String, Vector[Order]]
val cityTotals = orders.groupMapReduce(_.city)(_.totalPaise)(_ + _) // Map(Pune -> 200000, Delhi -> 30000)
val (unpaid, settled) = orders.partition(!_.paid)
val largest = orders.maxBy(_.totalPaise).id // o1
val bigIds = orders.collect { case Order(id, _, total, true) if total > 100000 => id } // Vector(o1)
val runningTotals = orders.scanLeft(0L)(_ + _.totalPaise) // Vector(0, 120000, 150000, 230000)
val cities = Set("Pune", "Delhi") + "Mumbai" // a new Set
val prepended = "x" :: List("y", "z") // List(x, y, z)
val updated = cityTotals.updated("Mumbai", 0L) // original map unchanged
val firstEvenSquares = (1 to 1_000_000).view.map(n => n * n).filter(_ % 2 == 0).take(3).toListList is not always the right default
Indexing into a List with list(i) is O(n). For random access or appending, use Vector (or ArrayBuffer locally). Use List when you mostly prepend and process from the head, as in recursion.
त्वरित जाँच: What happens when you call `updated` on an immutable Map?
- The original map is changed
- A new map is returned and the original is unchanged
- An exception is thrown
- The map becomes mutable
Answer
A new map is returned and the original is unchanged — Immutable collection operations return new collections, sharing structure where possible.