Skip to main content
Please wait...
Learn Scala: Scala Case Class
06 Apr, 2025

Learn Scala: Scala Case Class

A Scala case class is a specialized class designed for immutable data modeling and pattern matching. It provides several built-in features that simplify the creation and manipulation of instances. Here’s a detailed description of Scala case classes, their features, and some practical use cases.   

Key Features of Scala Case Classes 

  1. Automatic apply Method: The companion object of a case class automatically includes an apply method, which allows you to create instances without using the new keyword. This makes the syntax cleaner and more intuitive. 

  1. Immutable Fields: By default, the fields of a case class are immutable. This means that once an instance is created, its state cannot be changed. This immutability is a cornerstone of functional programming, as it helps avoid side effects and makes code easier to reason about. 

  1. Automatic equals, hashCode, and toString Methods: The Scala compiler automatically generates equals, hashCode, and toString methods based on the fields of the case class. This makes case classes suitable for use in collections that rely on these methods, such as sets and maps. 

  1. Pattern Matching: Case classes are designed to work seamlessly with Scala’s pattern matching feature. You can deconstruct instances of a case class in a concise and readable way, making it easier to work with complex data structures. 

  1. Copy Method: Case classes come with a built-in copy method that allows you to create a new instance with some fields modified while keeping the rest unchanged. This is particularly useful when you need to create a slightly modified version of an existing instance.

What the Scala Compiler Generates 

For each case class, the Scala compiler generates several useful methods and features: 

  1. apply Method: The companion object includes an apply method, which allows you to create instances without using the new keyword. 

  1. equals Method: The compiler generates an equals method that compares instances based on their fields. This makes case classes suitable for use in collections that rely on equality checks. 

  1. hashCode Method: The compiler generates a hashCode method based on the fields of the case class. This ensures that instances can be used in hash-based collections like sets and maps. 

  1. toString Method: The compiler generates a toString method that provides a string representation of the instance, including the values of its fields. 

  1. copy Method: The case class includes a copy method that allows you to create a new instance with some fields modified while keeping the rest unchanged. 

  1. unapply Method: The companion object includes an unapply method, which is used for pattern matching. This method returns an Option containing the fields of the instance, making it easy to deconstruct the instance in pattern matching expressions.

Use Case with Default Case Class Constructor Parameters 

Here’s an example of a case class Book with default constructor parameters: 

case class Book(title: String, author: String, year: Int = 2023) 
 
// Usage 
val defaultBook = Book("Scala Programming", "Jane Doe") 
val specificBook = Book("Scala Programming", "Jane Doe", 2022) 
  

In this example, the Book case class has a default value for the year parameter. This allows you to create instances without specifying all the parameters, making the code more flexible and easier to use. 

Use Case with Companion Object 

Consider a case class Person with a companion object that provides additional functionality: 

case class Person(name: String, age: Int) 
 
object Person { 
  def fromCSV(csv: String): Person = { 
    val parts = csv.split(",") 
    Person(parts(0), parts(1).toInt) 
  } 
} 
 
// Usage 
val csvData = "John Doe,30" 
val person = Person.fromCSV(csvData) 
  

In this example, the Person companion object includes a fromCSV method that parses a CSV string and creates a Person instance. This demonstrates how companion objects can be used to add factory methods and other utility function  

Use Case with Companion Object and unapply Method 

Here's an example of a case class Person with a companion object that includes an unapply method for pattern matching: 

case class Person(name: String, age: Int) 
 
object Person { 
  def unapply(person: Person): Option[(String, Int)] = Some((person.name, person.age)) 
} 
 
// Usage 
val person = Person("John Doe", 30) 
person match { 
  case Person(name, age) => println(s"Name: $name, Age: $age") 
} 
  

In this example, the unapply method in the companion object allows for pattern matching on Person instances, making it easy to extract and work with the fields. 

Conclusion 

Scala case classes are a powerful tool for modeling immutable data structures. They come with several built-in features that make them easy to use and integrate seamlessly with Scala’s functional programming and pattern matching capabilities. Whether you’re working with simple data models or complex data structures, case classes provide a concise and expressive way to define and manipulate your data. 

References 

Cunningham, H. Conrad. "Functional Programming in Scala Functional Data Structures (Chapter 3)."