在Kotlin中固定List大小的最佳方法是什么?

11

我有一个ParentObject列表。对于每个parentObject,它有2个childObject。

图像如下:

val listParent: MutableList<ParentObject> = mutableList() 

ParentObject {  
 ChildOjbect1{}   // object1 can not be NULL
 ChildOjbect2{}   // object2 can be NULL
}

同时,我想要建立一个ChildObject的mutableList。

val listChild: MutableList<ChildObject> = mutableList()  

list.add(parentObject.childOjbect1) // Because childObj1 can not be null  
parentOjbect.childObject2?.let { child ->  
  list.add(child)  
}

问题:
我只需要有6个项的listChild(基本上我想要固定大小为6的listChild)
我正在Kotlin中编写以下代码:

答案:
我只需要在Kotlin中使用以下代码来获取一个大小为6的listChild:

```kotlin val listChild = myList.take(6) ```
fun buildListChild(): List<ChildOjbect> {
  val listChild // instance mutable listChild
  forEach( parent: listParent) {
    listChild.add(parent.childObject1)
    parent.childOjbect2?.let {  it ->
    listChild.add(it)
  }
  return listChild.take(6)
}

我认为性能不好,因为它在所有的父项中循环。此外,我真的不想在添加之前总是检查listChild的大小。
那么解决这个问题的最佳方法是什么?

我认为性能表现不佳,因为它在所有的父项中进行循环。此外,我不想总是在添加之前检查listChild的大小。有没有更好的解决方法?


如果一个数组大小为6呢? - Geno Chen
我不知道你的意思是什么? - Bulma
我的意思是listchild的最大大小为6。它可以是3、4个项目,具体取决于listParent。 - Bulma
4个回答

10

您可以创建一个具有固定大小的列表或数组,但在这种情况下,您需要初始化它,例如val childList = arrayOfNulls<ChildObject>(6)(没有其他选项可以不初始化而拥有具有固定大小的数组),并在循环中检查它是否已满(或者在添加最后一个元素时)。如果是,则从方法返回。

在这种情况下,您不需要遍历所有父元素,然后再剪切它,只需进行简单的检查即可。


这是我想到的相同解决方案。我真的不想在添加之前总是检查列表的大小!!! - Bulma
我认为在任何情况下,您都需要进行一些检查,以了解何时从方法返回,以便您不必执行不必要的循环迭代。它可以使用一些外部库来实现,当列表已满(大小为6)时抛出异常,但他们仍将在内部执行相同的大小检查。如果您想要一些清晰的代码解决方案,请创建适当的自定义List类和方法。 - mr.kostua
@kostua 嗯,也许我们需要在添加之前每次检查子列表的大小。 代码看起来像这样: if (listChild.size < 6) { 添加子1 } parent.child2?.let { if(listChild.size < 6 ) 添加子2 } - Bulma

0

这是一个简单而完整的解决方案。

fun buildListChild(parents: List<ParentObject>) = parents
    .flatMap { listOfNotNull(it.childObject1, it.childObject2) }
    .take(6)
    .toMutableList()

或者你甚至可以按照以下方式避免创建嵌套列表。

fun buildListChild(parents: List<ParentObject>) = sequence {
    for (parent in parents) {
        yield(parent.childObject1)
        if (parent.childObject2 != null) {
            yield(parent.childObject2)
        }
    }
}.take(6).toMutableList()

0
你可以使用简化的语法(感谢@alexey-romanov的更新):
fun buildListChild() = parent
    .flatMap{it -> listOf(parent.childObject1, parent.childOjbect2)}
    .filterNotNull()

listOf()应该是不可变的。

如果对于列表的唯一引用是只读类型,我们可以将集合视为完全不可变。创建这样一个集合的简单方法如下:

val items = listOf(1, 2, 3)

目前,listOf()方法是使用数组列表实现的,但是在未来,可能会返回更多内存高效的完全不可变集合类型,利用它们知道无法更改的事实。


1
使用flatMap(something)代替map(something).flatMap {it} - Alexey Romanov
@MahdiPerfect正如您所说,我们仍然需要循环遍历父列表中的所有项目吗?这不是浪费时间吗? - Bulma
.flatMap{it -> listOf(parent.childObject1, parent.childOjbect2)} // 注意,childObject2 可能为 null。我们需要在这里进行检查吗? - Bulma

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接