内存中值相同的Lists/Tuples:val A=List(1,2,3)与val B=List(1,2,3)内存地址是否相同?
val A = List(1,2,3) and val B = List(1,2,3) point to the same memory address in Scala? Great question! Let’s unpack this and dive into how Scala handles memory allocation for immutable Lists and Tuples.
Short Answer
By default, no, A and B do not point to the same memory address. Each call to List(1,2,3) creates a new instance of the list structure, even if the values inside are identical. You can verify this with Scala’s eq operator, which checks for reference equality (unlike ==, which checks value equality):
val A = List(1,2,3) val B = List(1,2,3) println(A eq B) // Output: false (different references) println(A == B) // Output: true (same values)
Memory Allocation for Immutable Lists
Scala’s List is an immutable singly linked list, made up of Cons nodes (each holding a value and a reference to the next node) and a terminating Nil (empty list). Here’s how List(1,2,3) is structured in memory:
Cons(1, Cons(2, Cons(3, Nil)))
The key optimization here is structural sharing: since lists are immutable, we can safely reuse parts of existing lists to create new ones without copying data. For example:
val tail = List(2,3) val C = 1 :: tail // Prepends 1 to the existing tail val D = 1 :: tail // Does the same println(C eq D) // Output: true (same reference, since they share the tail)
In this case, both C and D point to the same new Cons(1, ...) node, which in turn points to the shared tail list. This saves memory by avoiding duplicate copies of identical sublists.
Note: The only exception to the "new instance per creation" rule is Nil—there’s exactly one global instance of the empty list, since it has no state to vary.
Memory Allocation for Tuples
Tuples in Scala are also immutable, but they’re structured differently than lists: each tuple size (e.g., Tuple2, Tuple3) is a separate class with fields for each element. Like lists, default behavior is to create a new instance for each tuple with identical values:
val t1 = (1,2,3) val t2 = (1,2,3) println(t1 eq t2) // Output: false (different tuple instances) println(t1 == t2) // Output: true (same element values)
A few edge cases here:
- The empty tuple
()(akaTuple0) has a single global instance, just likeNil, since it holds no data. - While the tuple instances themselves are unique, the elements inside may be pooled (e.g., small boxed integers from the JVM’s integer cache), but this doesn’t affect the tuple’s own reference.
When Would They Share the Same Address?
If you explicitly implement instance pooling (e.g., using a cache to reuse identical list/tuple instances), you could make A and B point to the same memory address. But this isn’t part of Scala’s standard library behavior—you’d have to build it yourself for specific use cases.
内容的提问来源于stack exchange,提问作者Muhammad Magdi Youssif

