7

Currently, I am learning Scala and reading this book Programming in Scala and which says, " Unlike an array or list, a tuple can hold objects with different types." For example, the following tuple contain Int, String and Float.

val tup = (1, "hello", 4.4)

Again, the book say, "If you want to have any type of element in list/array, then you can use Any Datatype."

val list = List[Any](1, "hello", 4.4)

So, what is the difference between above these 2 approaches? what are the benefit of one over another?

Ra Ka
  • 2,995
  • 3
  • 23
  • 31

4 Answers4

13

tup has type (Int, String, Double), so you can get data back with its correct type: tup._1 has type Int. list has type List[Any], so you've lost all type information: list(0)'s type is Any.

Don't use Any (or List[Any], etc.) unless you have to; certainly don't use it when a tuple will do.

Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • Thank you for your precise answer. So, using List[Any] means, all type information will be lost. I'll avoid using Any as less as possible. Thank you. – Ra Ka Dec 02 '16 at 04:45
9

Any is a data-type , just like Int or String, but different from them.
Tuple is a container, which can hold multiple data-types, i.e. it can contain vals of different data-types, but the type of the Tuple will depend upon how many elements are there in the Tuple, so for example:

val tup = (1, "hello", 4.4) // type of tup here is scala.Tuple3 (Int, String, Double)
val tup = (2.3, null) // type of tup here is scala.Tuple2  (Double, Null)
val tup = (5:Any, "hello", 2.2) // type of tup here is scala.Tuple3 (Any, String, Double)

But the type of each of the elements in the Tuple will be maintained. Any on the other hand, is like a homegenous data-type in which there's no unique type identity of the elements, be it a String or Int or Null type initially, will be converted to a single data-type Any and will lose all type-information.

Update:
The difference between a Tuple and a List[Any] is that a Tuple can hold elements of multiple data types, still maintaining the data type of the individual elements.
While a List or Array can only hold elements of a single data type, so a List[Any] will consist of all elements of type Any , so it'll basically convert all the elements (irrespective of their earlier data-type) to Any.

Shailesh
  • 2,116
  • 4
  • 28
  • 48
  • 1
    The comparison is between tuple and `List[Any]` (or `Array[Any]` or `Seq[Any]`), not between tuple and `Any` :) – Alexey Romanov Dec 02 '16 at 07:13
  • @AlexeyRomanov , sorry, my bad. Although my answer might explain that difference as well, I'll edit it. Thanks for pointing out :) – Shailesh Dec 02 '16 at 07:38
3

Tuples are type safe and with List[Any] you have to cast element to appropriate type.

val tup = (1, "hello", 4.4)
tup._2 --> gives you string

val list = List[Any](1, "hello", 4.4)
list(1) --> gives you object of type Any and you have to cast this object

Your tuple is a class of type Tuple3[Int, String, Double].

PawelN
  • 848
  • 7
  • 17
  • So, List[Any] is not type safe and there will be overhead of casting if used. Thank you for your explanation. – Ra Ka Dec 02 '16 at 04:41
  • Honestly, not only is overhead of casting trivial in most circumstances, code generated by the compiler for tuples (and for most uses of generics) has hidden casting too. Type safety is the only real concern but it's a very large one. – Alexey Romanov Dec 02 '16 at 07:41
-1

I don't agree with PawelN

val list = List[Any](1, "hello", 4.4)
for (i <- list) println(i.getClass)

or

val array = Array[Any](1, "hello", 4.4)
for (i <- array) println(i.getClass)

results in:

class java.lang.Integer
class java.lang.String
class java.lang.Double

Hence, no casting is needed when you access an item in a List or an Array of Any. Of course, I'd be suspicious of design of code that is using such a thing.

The main point of a Tuple, is for a function to be able to return arbitrary numbers of objects of different types. This is much lighter weight then creating a class every time you need to return multiple values at the cost of some type safety.

Clem Wang
  • 689
  • 8
  • 14
  • This is wrong @Clem Wang. Try to do some operation on the items of list = List[Any](1, "hello", 4.4) and you will find it. – soumya-kole Oct 03 '20 at 14:21