
- Scala - Home
- Scala - Overview
- Scala - Features
- Scala - Environment Setup
- Scala - Build Tool (SBT)
- Scala - REPL
- Scala - Dot & Dotty
- Scala - Basic Syntax
- Scala - Hello World Program
- Scala - Identifiers
- Scala - Keywords
- Scala - Comments
- Scala - Code Blocks
- Scala - Semicolon
- Scala - Constructs
- Scala - Expressions
- Scala - Input and Output
- Scala - Optional Braces
- Scala - Underscore (_)
- Data Types and Variables
- Scala - Data Types
- Scala - Type Bounds
- Scala - Context Bound
- Scala - Variances
- Scala - Type Hierarchy
- Scala - Variables
- Scala - Variable Scopes
- Scala - Literals
- Scala - Numeric Types
- Scala - Boolean Types
- Scala - Char Type
- Scala - Unit Types
- Scala - Strings
- Scala - Arrays
- Scala - Null Type
- Scala - Nothing
- Scala - Any Type
- Scala - AnyRef Type
- Scala - Unified Types
- Scala - Dates and Times
- Scala - Ranges
- Scala - Multidimensional Arrays
- Scala - WrappedArray
- Scala - StringBuilder
- Scala - String Interpolation
- Scala - StringContext
- Scala - Type Casting
- Scala var vs val
- Scala Operators
- Scala - Operators
- Scala - Rules for Operators
- Scala - Arithmetic Operators
- Scala - Relational Operators
- Scala - Logical Operators
- Scala - Bitwise Operators
- Scala - Assignment Operators
- Scala - Operators Precedence
- Scala - Symbolic Operators
- Scala - Range Operator
- Scala - String Concatenation Operator
- Scala Conditional Statements
- Scala - IF ELSE
- Scala - IF-ELSE-IF-ELSE Statement
- Scala - Nested IF-ELSE Statement
- Scala Loop Statements
- Scala - Loop Statements
- Scala - while Loop
- Scala - do-while Loop
- Scala - Nested Loops
- Scala - for Loop
- Scala - break Statement
- Scala - yield Keyword
- Scala Classes & Objects
- Scala - Classes & Objects
- Scala - Constructors
- Scala - Auxiliary Constructor
- Scala - Primary Constructor
- Scala - This Keyword
- Scala - Nested Classes
- Scala - Getters and Setters
- Scala - Object Private Fields
- Scala - Singleton Object
- Scala - Companion Objects
- Scala - Creating Executable Programs
- Scala - Stateful Object
- Scala - Enumerations
- Scala - Polymorphism
- Scala - Access Modifiers
- Scala - Apply Method
- Scala - Update Methods
- Scala - UnapplySeq Method
- Scala - Inheritance
- Scala - Extending a Class
- Scala - Method Overloading
- Scala - Method Overriding
- Scala - Generic Classes
- Scala - Generic Functions
- Scala - Superclass Construction
- Scala Methods & Functions
- Scala - Functions
- Scala - Main Methods
- Scala - Functions Call-by-Name
- Scala - Functions with Named Arguments
- Scala - Function with Variable Arguments
- Scala - Recursion Functions
- Scala - Default Parameter Values
- Scala - Functions without Parameters
- Scala - Implicit Parameters
- Scala - Higher-Order Functions
- Scala - Nested Functions
- Scala - Extension Methods
- Scala - Anonymous Functions
- Partially Applied Functions
- Scala - Lazy Val
- Scala - Pure Function
- Scala - Currying Functions
- Scala - Control Abstractions
- Scala - Corecursion
- Scala - Unfold
- Scala - Tail Recursion
- Scala - Infinite Sequences
- Scala - Dynamic Invocation
- Scala - Lambda Expressions
- Scala Collections
- Scala - Collections
- Mutable and Immutable Collections
- Scala - Lists
- Scala - Sets
- Scala - Maps
- Scala - TreeMap
- Scala - SortedMap
- Scala - Tuples
- Scala - Iterators
- Scala - Options
- Scala - Infinite Streams
- Scala - Parallel Collections
- Scala - Algebraic Data Types
- Scala Pattern Matching
- Scala - Pattern Matching
- Scala - Type Patterns
- Scala - Exception Handling
- Scala - Extractors
- Scala - Regular Expressions
- Scala Files I/O
- Scala - Files I/O
- Scala Advanced Concepts
- Scala - Closures
- Scala - Futures
- Scala - Promises
- Scala - Traits
- Scala - Trait Mixins
- Scala - Layered Traits
- Scala - Trait Linearization
- Scala - Sealed Traits
- Scala - Transparent Traits
- Scala - Literal Type Arithmetic
- Scala - Inline keyword
- Scala - Def, Var & Val
- Scala - Dropped Features
- Scala - BDD Testing
Scala - Lazy Val
This chapter takes you through the concept of lazy val in Scala programming. You can use the lazy val to delay the evaluation of a variable until it is accessed for the first time. So, it optimizes performance and resource usage.
The lazy val
The lazy val is a keyword that defines a lazily evaluated variable. Unlike regular val declarations. The lazy val is not initialized until it is referenced. It is used in expensive computations and when the value may not be needed immediately.
The lazy val is declared with the "lazy" keyword followed by the "val" keyword. So, this value is evaluated only once and the result is cached for subsequent accesses.
Syntax
The syntax of a lazy val in Scala is -
lazy val variableName: DataType = expression
Example of Lazy Val
The following example shows defining and using a lazy val in Scala programming
object Demo { lazy val expensiveComputation: Int = { println("Performing expensive computation...") 42 } def main(args: Array[String]): Unit = { println("Before accessing lazy val") println(expensiveComputation) println(expensiveComputation) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Before accessing lazy val Performing expensive computation... 42 42
In the example, the expensiveComputation is not evaluated until it is accessed for the first time. Subsequent accesses do not trigger the computation again because the result is cached.
Advantages of lazy val
There are various advantages of using lazy val. It can optimize performance and save resources. It also improves application responsiveness.
Lazy values avoid unnecessary calculations where the value may never be used during the execution of the program. The lazy val can also resolve circular dependencies in some cases. It delays the evaluation until all dependencies are properly initialized.
lazy val with Collections
You can use lazy val with collections for improving performance when dealing with large datasets and tough operations.
Syntax
The syntax for using lazy val with collections is -
lazy val collectionName: CollectionType = collectionExpression
Example
Consider the example of using lazy val with collections in Scala programming -
object Demo { lazy val largeList: List[Int] = { println("Initializing large list...") List.range(1, 1000000) } def main(args: Array[String]): Unit = { println("Before accessing lazy val") println(largeList.head) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Before accessing lazy val Initializing large list... 1
In the example, the largeList is not initialized until it is accessed for the first time. So it delays the expensive operation of creating a large list until it is actually needed.
Combining lazy val with def
While lazy val delays initialization until first access. You can define def methods that are evaluated every time they are called. You can combine these for flexibility in initialization.
Syntax
The syntax for combining lazy val with def is -
def methodName: ReturnType = lazyValueName lazy val lazyValueName: Type = expression
Example
Consider the example of combining lazy val with def in Scala programming -
object Demo { lazy val currentTime: Long = { println("Fetching current time...") System.currentTimeMillis() } def getCurrentTime: Long = currentTime def main(args: Array[String]): Unit = { println("Before accessing lazy val") println(getCurrentTime) println(getCurrentTime) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Before accessing lazy val Fetching current time... <timestamp> <timestamp>
In the example, currentTime is not evaluated until getCurrentTime is called for the first time. Subsequent calls to getCurrentTime return the cached value.
lazy val with Singleton Objects
You can use lazy val in singleton objects. It is used for initializing resources and configurations that should only be loaded once.
Syntax
The syntax for using lazy val with singleton objects is -
object SingletonObject { lazy val valueName: Type = expression }
Example
Consider the example of using lazy val in a singleton object in Scala programming -
object Configuration { lazy val config: Map[String, String] = { println("Loading configuration...") Map("host" -> "localhost", "port" -> "8080") } } object Demo { def main(args: Array[String]): Unit = { println("Before accessing lazy val") println(Configuration.config) println(Configuration.config) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Before accessing lazy val Loading configuration... Map(host -> localhost, port -> 8080) Map(host -> localhost, port -> 8080)
In the example, the config is not loaded until it is accessed for the first time. So that the configuration is only loaded once.
lazy val and Thread Safety
The lazy val is thread-safe in multi-threaded environment. It guarantees that the value is initialized only once even if accessed concurrently.
Example
Consider the example of using lazy val in a multi-threaded environment in Scala programming -
object Demo { lazy val safeValue: Int = { println("Initializing safe value...") 42 } def main(args: Array[String]): Unit = { val threads = (1 to 10).map(_ => new Thread(() => println(safeValue))) threads.foreach(_.start()) threads.foreach(_.join()) } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Initializing safe value... 42 42 42 42 42 42 42 42 42 42
In the example, safeValue is initialized only once even though multiple threads access it concurrently.
Performance Considerations
While lazy val can improve performance by delaying initialization. But it may introduce overhead due to synchronization.
Example
Consider the example of performance considerations with lazy val in Scala programming -
object Demo { lazy val cachedValue: Int = { println("Performing expensive computation...") Thread.sleep(1000) 42 } def main(args: Array[String]): Unit = { val start = System.currentTimeMillis() println(cachedValue) println(cachedValue) val end = System.currentTimeMillis() println(s"Time taken: ${end - start} ms") } }
Save the above program in Demo.scala. Use the following commands to compile and execute this program.
Command
> scalac Demo.scala > scala Demo
Output
Performing expensive computation... 42 42 Time taken: 1001 ms
In the example, the cachedValue is initialized only once. Hence, the lazy val has the advantage of saving time because it avoids unnecessary calculations.
Lazy Val Summary
- The lazy val in Scala is a value that is not initialized until it is accessed for the first time.
- It enhances performance because it defers expensive computations and avoid unnecessary evaluations.
- The lazy val can be used with collections, singleton objects, and in multi-threaded environments.
- You can combine lazy val with def. So, it provides flexibility in initialization.