I'm converting a Java application to Kotlin. In one area it's using apache IO's FileUtils listFiles functions.
These return collections and I'm having problems converting/casting the collections into ArrayList
val myFiles = FileUtils.listFiles(mediaStorageDir, extensions, true) as ArrayList<File>
Whilst this compiles I get a runtime error as follows:
java.util.LinkedList cannot be cast to java.util.ArrayList
What's the correct way to convert a collection object into an ArrayList?
You can easily create ArrayList in Kotlin from any Collection
val collection = FileUtils.listFiles(mediaStorageDir, extensions, true)
val arrayList = ArrayList(collection)
ArrayList is a class with implementation details. FileUtils is returning a LinkedList and that is why you are having issues. You should do a cast to List<File> instead since it is an interface that both ArrayList and LinkedList implement.
If you would need to modify the returned list you can use MutableList<File> instead the immutable one.
But this is not the best approach because if the creators of FileUtils later change the implementation details of their collections your code may start crashing.
A better soulition if explicitly need it to be an arrayList instead of a generic list could be:
val myFiles = FileUtils.listFiles(mediaStorageDir, extensions, true)
val array = arrayListOf<File>()
array.addAll(myFiles)
The as operator is a cast. But a cast does not convert a value to a given type; a cast claims that the value is already of that type.
A LinkedList is not an ArrayList, so when you claim it is, the computer will call you out on your mistake — as you see!
Instead, you need* to convert the value. Perhaps the best way is to call the extension function .toArrayList(). Alternatively, you could call the constructor explicitly: ArrayList(…).
(* This assumes you actually need an ArrayList. In practice, it's usually much better to refer only to the interface, in this case List or MutableList. As per other comments, the function you're calling is declared to return a Collection; the current implementation may return a LinkedList for you now, but that could change, so it's safest not to assume it implements either of those interfaces, and instead to call .toList() or .toMutableList().)