2

Having a list of Data

val list: List<Data>

And want to make a shallow copy of it into a new list.

There are a few ways could do it in kotlin, wondering which one should be used in which case?

list?.filter is similar to mutableListOf, but listOf seems different.

Anyone suggestion?

val copyData = list?.filter{true}

copyData = mutableListOf(list)

copyData = listOf(list)
Roland
  • 22,259
  • 4
  • 57
  • 84
lannyf
  • 9,865
  • 12
  • 70
  • 152

2 Answers2

4

The latter two options, mutableListOf(list) and listOf(list), don't actually copy a list, they only create a new list which has a single item pointing to the list. This is not a shallow copy of list, because you cannot observe its older content as it changes.

The list.filter { true } option works, i.e. you get a new list that is a copy of list, but it is not an idiomatic solution as it might hurt readability of the code.

Instead, consider list.toList() and list.toMutableList(), based on the desired mutability.

hotkey
  • 140,743
  • 39
  • 371
  • 326
  • thx @hotkey! the list.toList() seems is same as toMutibleList()? list.toMutableList() ==> public fun Collection.toMutableList(): MutableList { return ArrayList(this) } ; and list.toList() ==> inline fun java.util.Enumeration.toList(): List = java.util.Collections.list(this) ; which call into public static ArrayList list(Enumeration e) { ArrayList l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); return l; } – lannyf Aug 09 '18 at 15:41
  • They are similar, though the list they return is exposed as an instance of different interfaces: the Kotlin `List`, unlike Java, is an interface for read-only lists, and `MutableList` has mutating functions. See: https://stackoverflow.com/questions/46445909/difference-between-mutablelist-and-list-in-kotlin, and the docs: https://kotlinlang.org/docs/reference/collections.html – hotkey Aug 09 '18 at 17:16
1

Use filter if you really want to filter the incoming list and work with the filtered one instead. Using filter{true} doesn't really make sense.

Use toMutableList if you need to adapt the returned list, e.g. you need to add additional elements or remove some.

Finally, use toList if you require a new list containing the same elements, which doesn't allow adding/removing elements. You may also want to check the Kotlin reference regarding Collections: List, Set, Map

The ones you mentioned, i.e. mutableListOf and listOf are just convenience methods to create new lists containing whatever you passed.. so you actually constructed a list of lists.

Roland
  • 22,259
  • 4
  • 57
  • 84
  • thx @Roland!. filter{true} could be useful in the case the copy does not want be affected by the source's change. i.e. when giving the list snapshot to listView's adapter, it may not want to be affected by the original source list's change later. – lannyf Aug 09 '18 at 14:44
  • `filter { true }` is basically just the same as calling `toList()` ;-) I really recommend you the last link I added regarding the collections. Most of the methods return immutable collections, except you call something like `mutableListOf`, `mutableMap`, etc. – Roland Aug 09 '18 at 14:47