Kotlin中如何无额外内存分配将Set转为元素后带逗号的可变参数?
解决方案
要实现你需要的「每个名字后跟逗号作为参数传入log」的效果,首先得明确:必须分配新数组——原Set只有n个元素,而我们需要2n个参数(每个名字+逗号),没有现成的结构可以直接复用,这是逻辑上的必然。不过可以优化分配方式,避免额外的中间数组开销,直接一步构建目标数组:
每个元素后都加逗号(含最后一个)
fun scenario(names: Set<String>) { if (names.isEmpty()) { log() return } // 直接创建刚好容纳所有参数的数组 val args = arrayOfNulls<Object>(names.size * 2) var index = 0 for (name in names) { args[index++] = name args[index++] = "," } // 展开数组传入可变参数 log(*args) }
最后一个元素不加逗号(更符合常规输出逻辑)
如果你的实际需求是最后一个名字后不需要逗号,可以调整数组大小并处理边界:
fun scenario(names: Set<String>) { when (names.size) { 0 -> log() 1 -> log(names.first()) else -> { val args = arrayOfNulls<Object>(names.size * 2 - 1) var index = 0 val iterator = names.iterator() while (iterator.hasNext()) { val name = iterator.next() args[index++] = name // 只有后面还有元素时才加逗号 if (iterator.hasNext()) { args[index++] = "," } } log(*args) } } }
关于内存分配的说明
你之前用*names.toTypedArray()的方式,本质是先把Set转成n个元素的数组,这个数组完全没法满足插入逗号的需求——因为我们需要的是混合了名字和逗号的参数列表,必须构造新数组来承载这些交替的元素。
另外要注意:Kotlin的可变参数(varargs)底层就是数组实现的,哪怕你直接写log("John", ",", "Alice"),编译器也会自动创建一个Object[]来装这些参数。所以不存在「完全不分配内存」的可能,只能尽量减少不必要的中间分配(比如避免先转Set为数组再二次处理)。
内容的提问来源于stack exchange,提问作者Pârvănescu Stefan
相关产品推荐
相关产品推荐

