19

Is there any method in kotlin which replaces below two line into one. I know i can create a extension function but I'm eager to know if it already exist in kotlin. Something like listOfChecklist.clearAndAddAll().

listOfChecklist.clear()
listOfChecklist.addAll(newList)

This is what I'm doing now manually using an extension function. But I hope there is a better solution.

fun <E> MutableCollection<E>.clearAndAddAll(replace: MutableSet<E>) {
    clear()
    addAll(replace)
}
Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
Sai
  • 15,188
  • 20
  • 81
  • 121
  • 3
    Not actually relevant, but there is [`retainAll`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/retain-all.html) function that removes all the items not contained in another collection, though it doesn't add the missing ones. – hotkey Jan 13 '17 at 11:31
  • @s1m0nw1 There is no such method. Instead you can use the extension method like above. – Sai Oct 04 '17 at 06:31
  • @miensol, why hope? It's a standard operation to set new items without recreating a list. – CoolMind Aug 02 '18 at 14:29
  • 2
    @CoolMind In Android, We use listview with an adapter to show a list of elements. The adapter takes in listOfChecklist as a parameter once we pass the list to the adapter it binds together, the only thing we can do is add or remove items in listOfChecklist which will automatically update the listview once we notify adapter. If we change the reference to new list "listOfChecklist = newlist" and boom, we are doomed and we can only see empty listview. To bring back listview, recreate everything after changing the reference which is a time-consuming job. So I was looking for clearAndAddAll. – Sai Aug 03 '18 at 19:42
  • @SaiKiran, I agree with you and do the same. So, your method is useful. – CoolMind Aug 14 '18 at 15:43

2 Answers2

18

It's not possible to do this. An idiomatic way to solve your case would be using a scope function like with.

val list = mutableListOf<String>()

with(list){
    clear()
    addAll(arrayListOf())
}
s1m0nw1
  • 76,759
  • 17
  • 167
  • 196
1

My answer will be rather philosophical, so here are my thoughts:

  1. If you really feel the need to merge these 2 operations into one line of code, it suggests you use this very often.

  2. If you use this design pattern very often, it seems to me that there is something quite wrong in your overall design of your application/class and here I totally agree with the "I hope there's no such method" comment by @miensol.

  3. If you don't use it often, I think that leaving it on 2 lines of code makes it much more readable.

  4. Clearing the "listOfChecklist" makes sense only if "newlist" gets cleared at some point too, otherwise you could just keep the reference like: "listOfChecklist = newlist" and boom! You're done ...

  5. If you use mutable lists a lot, which are being cleared and their elements are being copied between each other, again, it seem to me as an over-use of mutable state, which makes your code difficult to reason about. I would suggest to look at some core functional programming principles which will get you rid of the clear/addAll concerns completely :-).

  6. I am not a performance expert, but for most of the use cases I don't really see a reasonable benefit of reusing an existing list instead of just simply cloning it (if you really need to keep the elements for some reason) and speaking of performance itself, the JVM almost always does a good job anyway.

Conclusion: What I would suggest is to keep it on 2 lines if you really need it or design your code in a way so that you completely avoid the need for clear/addAll. Otherwise you can just go with your extension function or whatever makes you feel happy.

  • 1
    You are absolutely right but in case of android, We use listview with an adapter to show a list of elements. The adapter takes in listOfChecklist as a parameter once we pass the list to the adapter it binds together, the only thing we can do is add or remove items in listOfChecklist which will automatically update the listview once we notify adapter. If we change the reference to new list "listOfChecklist = newlist" and boom, we are doomed and we can only see empty listview.To bring back listview, recreate everything after changing the reference which is a time-consuming job. So clearAndAddAll – Sai Aug 03 '18 at 19:36
  • I should explain a bit more, in my question. I will update it when soon. – Sai Aug 03 '18 at 19:39
  • 1
    Saying "bad design" is like a doctor diagnosing a patient without seeing him. There are times when it is certainly true, and sometimes it is not, there is a bit more to it: https://stackoverflow.com/questions/6961356/list-clear-vs-list-new-arraylistinteger If you want to keep the list size, clear() is better than creating a new. – user2424380 May 18 '20 at 11:33
  • 1
    Coming back after a few years of experience in programming. Your points perfectly make sense to me now. Avoid clear/addAll all together use newlists directly, and just in case if we end up using clear/addAll using two lines makes the code more readable. – Sai Jul 21 '20 at 07:10