Kotlin merge two nullable mutable list
Asked Answered
B

4

30
val mutableList1: MutableList<TeamInvitationData?>?
val mutableList2: MutableList<TeamInvitationData?>?

addAll method can be use to merge nullable mutable list but, here it throws me compile time error.

Example:

val map1 = listOne?.map { TeamInvitationData(it) }
val map2 = listTwo?.map { TeamInvitationData(it) }
map1.addAll(map2)

Type interface failed ,Please try to specify type argument explicitly.

Here Any way can I merge this two array , thanks in advance.

Burlington answered 12/1, 2018 at 11:22 Comment(4)
On what line did the error occur? Why don't you show the code you actually wrote?Carthusian
this one have same code actually I did and unbox from the other element.Burlington
You have shown no code that attempts to use addAll. You don't show any line of code that would need type inference, either.Carthusian
You pasted two snippets that don't combine into a whole. My best guess is that you expect map1 and map2 to be MutableList because listOne and listTwo are mutable, but map actually returns an immutable List and so you can't call addAll on it. While your question is about merging mutable lists, your code doesn't attempt that.Carthusian
P
47

Here are couple of solutions.

  1. In case if you need to add all elements to mutableList1:

    val mutableList1: MutableList<Any?>? = ...
    val mutableList2: MutableList<Any?>? = ...
    
    mutableList1?.let { list1 -> mutableList2?.let(list1::addAll) }
    
  2. In case if you need new nullable list as result:

    val mutableList1: MutableList<Any?>? = ...
    val mutableList2: MutableList<Any?>? = ...
    
    val list3: List<Any?>? = mutableList1?.let { list1 ->
        mutableList2?.let { list2 -> list1 + list2 }
    }
    
  3. In case if you need new nullable mutable list as result:

    val mutableList1: MutableList<Any?>? = ...
    val mutableList2: MutableList<Any?>? = ...
    
    val list3: MutableList<Any?>? = mutableList1
            ?.let { list1 -> mutableList2?.let { list2 -> list1 + list2 } }
            ?.toMutableList()
    
  4. In case if you need new non-null list as result:

    val mutableList1: MutableList<Any?>? = ...
    val mutableList2: MutableList<Any?>? = ...
    
    val list3: List<Any?> = mutableList1.orEmpty() + mutableList2.orEmpty()
    
Privation answered 12/1, 2018 at 11:29 Comment(4)
Is it necessary to use inner let ? but I like 4th one.Burlington
@Burlington you can replace inner let with if (list != null) ... else null but it will look massive comparing to ?.letPrivation
Against of null , Let seem perfect.Burlington
My Java intuition betrayed me on the last example, i didn't realize you can declare extensions on nullable types.Carthusian
E
6

plus. Returns an List containing all elements of the original collection and then the given Iterable. source

Collection<T>.plus(elements: Iterable<T>): List<T>

Another Good read here

Ethanol answered 30/12, 2019 at 7:5 Comment(0)
C
2

Based on your snippets, which don't make a consistent whole, I made some guesses as to what you actually wanted to achieve:

val mutableList1: MutableList<String?>? = ...
val mutableList2: MutableList<String?>? = ...

val mapped1 = mutableList1?.mapTo(ArrayList()) { TeamInvitationData(it) }
val mapped2 = mutableList2?.mapTo(ArrayList()) { TeamInvitationData(it) }

mapped1?.addAll(mapped2.orEmpty())

The key point to note is that map() returns an immutable list regardless of the type of the input list. To get a mutable list you must use mapTo(destination) { ... }. Once that is fixed, you can use addAll() as shown in the last line.

Carthusian answered 12/1, 2018 at 16:45 Comment(0)
A
0

The answer given by @hluhovskyi is a good one, but there is one more posibility from his second option, where you need new nullable list as result:

In case if you need new nullable list as result:

val mutableList1: MutableList<Any?>? = ... val mutableList2: MutableList<Any?>? = ...

val list3: List<Any?>? = mutableList1?.let { list1 -> mutableList2?.let { list2 -> list1 + list2 } }

In this exmaple, in case mutableList1 is empty, you will have automatically and empty list ignoring if the mutableList2 has elements.

So, if you need the sum of the two lists and need a nullable list only if the two lists are null, you will need to do:

val mutableList1: MutableList<Any?>? = ...
val mutableList2: MutableList<Any?>? = ...

val list3: List<Any?>? = mutableList1?.let { list1 ->
    mutableList2?.let { list2 -> list1 + list2 } 
    ?: list1
} ?: mutableList2

So, now you will have as result:

  1. Null list if both were null at the begining
  2. The sum of both list if both were not null
  3. In case one is null and the other have elemnts, it will return the list with elements.
Anguished answered 19/12, 2022 at 20:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.