Why would the Use case 1 (arrayOf
) print the cryptic object address while ArrayList
correctly understands and print the object properties. It is odd because, not just ArrayList
, but setOf
, listOf
etc. all print the object properties correctly. It's seems arrayOf
is somehow different.
data class Student(
val id: String,
val name: String
)
fun main() {
val hello1 = Student("1", "A")
val hello2 = Student("2", "B")
// USE CASE 1
val arr = arrayOf(hello1, hello2)
println(arr)
// OUTPUT: [LStudent;@37f8bb67
//USE CASE 2
val arr2 = ArrayList<Student>()
arr2.add(hello1)
arr2.add(hello2)
println(arr2)
// OUTPUT: [Student(id=1, name=A), Student(id=2, name=B)]
}
CodePudding user response:
Yes, arrayOf
is somehow different… It's (like in) Java, it does not have a toString()
method, but in Kotlin, it has a joinToString(…)
which you can easily use in order to mimic the built-in toString()
of Java/Kotlin collections:
fun main(args: Array<String>) {
// prepare an array
val hello1 = Student("1", "A")
val hello2 = Student("2", "B")
val arr = arrayOf(hello1, hello2)
// join its items to a String with separator, prefix and postfix
val joinedToString = arr.joinToString(", ", "[", "]")
// and print it
println(joinedToString)
}
Result:
[Student(id=1, name=A), Student(id=2, name=B)]
As mentioned (and answered) by @Joeffrey, you can do that with less code since there's Array.contentToString()
:
The very same output as above can be achieved through
fun main(args: Array<String>) {
// prepare an array
val hello1 = Student("1", "A")
val hello2 = Student("2", "B")
val arr = arrayOf(hello1, hello2)
// and print it using a specific (new?) method for it
println(arr.contentToString())
}
CodePudding user response:
It is odd because, not just
ArrayList
, butsetOf
,listOf
etc. all print the object properties correctly. It's seemsarrayOf
is somehow different.
Yes it is different, and maybe it's more different than you thought. I'm not exactly sure where the confusion occur so let me clarify some things.
To start with, arrayOf
doesn't give you an ArrayList
, it returns an Array
, which is a different type. So there is no real reason to expect their toString
to behave similarly. You might be confusing arrayOf
with arrayListOf
, which would indeed give you an ArrayList
.
An ArrayList
is a subtype of List
, which is itself a subtype of Collection
. ArrayList
just happens to be a collection that is backed by an array (hence the name), but it doesn't make it an array itself. Also, there are many other types of lists.
The other builders you mention here (and that behave as you expect) return Collection
subtypes:
listOf()
may return any subtype ofList
(includingArrayList
)setOf()
may return any subtype ofSet
Collections
have a nice toString()
implementation that prints their elements. Arrays don't have a specific toString()
method implementation, and only have the default one (this is legacy from Java), hence the type and memory address in the output.
However, you can use the contentToString extension on arrays to have a similar result as collections' toString()
output:
val hello1 = Student("1", "A")
val hello2 = Student("2", "B")
val arr = arrayOf(hello1, hello2)
println(arr) // prints: [LStudent;@37f8bb67
println(arr.contentToString()) // prints: [Student(id=1, name=A), Student(id=2, name=B)]
val list = arrayListOf(hello1, hello2)
println(list) // prints: [Student(id=1, name=A), Student(id=2, name=B)]
Note that you shouldn't really use arrays in business code in Kotlin, as most stdlib APIs revolve around List
and other collections. Arrays should probably be considered more low-level primitives in Kotlin.