在Java中,我们可以执行以下操作
public class TempClass {
List<Integer> myList = null;
void doSomething() {
myList = new ArrayList<>();
myList.add(10);
myList.remove(10);
}
}
Run Code Online (Sandbox Code Playgroud)
但如果我们直接将其重写为Kotlin,如下所示
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
Run Code Online (Sandbox Code Playgroud)
我从我的列表中得到了没有找到add并remove运行的错误
我努力将它转换为ArrayList,但这需要投射它是奇怪的,而在Java中不需要.这就违背了抽象类List的目的
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法让我使用List但不需要投射它,就像在Java中可以做到的那样?
在Java 8中,Stream.collect允许对集合进行聚合.在Kotlin中,除了作为stdlib中的扩展函数的集合之外,它不以相同的方式存在.但目前尚不清楚不同用例的等价性.
例如,在JavaDocCollectors的顶部是为Java 8编写的示例,当将它们移植到Kolin时,在不同的JDK版本上不能使用Java 8类,因此它们应该以不同的方式编写.
在网上显示Kotlin集合示例的资源方面,它们通常是微不足道的,并没有真正与相同的用例进行比较.什么是真正符合Java 8记录的案例的好例子Stream.collect?那里的清单是:
以上链接的JavaDoc中的详细信息.
注意: 这个问题是由作者故意编写和回答的(自答案问题),因此对于常见问题的Kotlin主题的惯用答案存在于SO中.还要澄清为Kotlin的alphas写的一些非常古老的答案,这些答案对于当前的Kotlin来说是不准确的.
我正在编写一小段代码,我在内部处理可变映射中的数据,而后者又有可变列表.
我想将我的数据暴露给API用户,但为了避免任何不安全的数据发布,我想在不可变集合中公开它,即使内部由可变集合处理也是如此.
class School {
val roster: MutableMap<Int, MutableList<String>> = mutableMapOf<Int, MutableList<String>>()
fun add(name: String, grade: Int): Unit {
val students = roster.getOrPut(grade) { mutableListOf() }
if (!students.contains(name)) {
students.add(name)
}
}
fun sort(): Map<Int, List<String>> {
return db().mapValues { entry -> entry.value.sorted() }
.toSortedMap()
}
fun grade(grade: Int) = db().getOrElse(grade, { listOf() })
fun db(): Map<Int, List<String>> = roster //Uh oh!
}
Run Code Online (Sandbox Code Playgroud)
我设法只在我的类的公共API中公开Map和List(它是不可变的),但我实际暴露的实例仍然具有固有的可变性.
这意味着API用户可以简单地将我返回的地图强制转换为ImmutableMap,并获得对我的类内部的宝贵私有数据的访问权限,这些私有数据旨在受到这种访问的保护.
我找不到在收集工厂方法一个拷贝构造函数mutableMapOf()或mutableListOf(),所以我想知道什么是将可变集合到一个不变的一个最好的和最有效的方式.
有什么建议或建议吗?
如果我有immutableMap: Map<String, Int>并希望将其转换为a mutableMap: MutableMap<String, Int>,那么最好的方法是什么?似乎没有任何方便的方式.
我有一个Java/Kotlin互操作问题.一个Kotlin不可变列表被编译成一个可变的普通java.util.ArrayList!
Kotlin(图书馆):
class A {
val items: List<Item> = ArrayList()
}
Run Code Online (Sandbox Code Playgroud)
Java(消费者):
A a = new A();
a.getItems().add(new Item()); // Compiles and runs but I wish to fail or throw
Run Code Online (Sandbox Code Playgroud)
如何从Java角度使我的Kotlin类完全不可变?
是否有关于Java 8功能的最新概述,Kotlin尚不支持?
例如,调用Map#putIfAbsent等默认方法无法编译(不支持的引用错误):
import java.util.*
fun main(args: Array<String>) {
val x : Map<Int, Int> = HashMap<Int, Int>()
x.putIfAbsent(1, 2)
}
Run Code Online (Sandbox Code Playgroud)
如果覆盖默认方法,则它可以工作:
import java.util.*
fun main(args: Array<String>) {
val x : HashMap<Int, Int> = HashMap<Int, Int>()
x.putIfAbsent(1, 2)
}
Run Code Online (Sandbox Code Playgroud)
这就是我通过实验发现的,但是为了决定是否已经可以从Java 8代码基础迁移到Kotlin,系统的概述将是有价值的.
更新:我的示例中的代码是由"Java to Kotlin"转换器创建的.正如user2235698指出的那样,Map<Int, Int>是一个不可变的Kotlin地图.但是,当我将其更改为java.util.Map地图时,该示例无法编译.然而,我声称它必须使用默认方法做一些事情会产生误导.
由于它超出了这个问题的范围,我在这里开了一个后续问题:java.util.HashMap在Kotlin中没有实现java.util.Map吗?
我们知道Kotlin中的List是不可变的,即你不能像下面那样添加和删除.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果我们将它转换为ArrayList,如下所示,添加和删除工作.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
Run Code Online (Sandbox Code Playgroud)
我只是觉得这很奇怪,因为myList实际上是一个List,它假设是不可变的.铸造它,允许它被改变.
上面做了什么(强制转换为Array并修改内容)是合法的,还是语言需要改进才能禁止?
我想要一个接受只读列表的数据类:
data class Notebook(val notes: List<String>) {
}
Run Code Online (Sandbox Code Playgroud)
但它也可以接受MutableList,因为它是一个子类型List.
例如,以下代码修改传入的列表:
fun main(args: Array<String>) {
val notes = arrayListOf("One", "Two")
val notebook = Notebook(notes)
notes.add("Three")
println(notebook) // prints: Notebook(notes=[One, Two, Three])
}
Run Code Online (Sandbox Code Playgroud)
有没有办法如何在数据类中执行传入列表的防御副本?
我已经开始使用Kotlin作为java的替代品并且非常喜欢它.但是,如果没有跳回到java-land,我一直无法找到解决方案:
我有一个Iterable<SomeObject>并且需要将其转换为列表,因此我可以多次迭代它.这是一个不可变列表的明显应用,因为我需要做的就是多次读取它.我如何在开始时将这些数据实际放入列表中?(我知道这是一个界面,但我一直无法在文档中找到它的实现)
可能的(如果不满意)解决方案:
val valueList = arrayListOf(values)
// iterate through valuelist
Run Code Online (Sandbox Code Playgroud)
要么
fun copyIterableToList(values: Iterable<SomeObject>) : List<SomeObject> {
var outList = ArrayList<SomeObject>()
for (value in values) {
outList.add(value)
}
return outList
}
Run Code Online (Sandbox Code Playgroud)
除非我误解,否则这些最终MutableLists会有效,但感觉就像是一种解决方法.是否有类似的immutableListOf(Iterable<SomeObject>)方法将实例化一个不可变的列表对象?
我想知道如何在Kotlin中制作可调整大小的二维数组.
C++示例: vector< vector<int> > my_vector
我尝试过的: var seqList: List<List<Int>> = ArrayList<ArrayList<Int>>()
但是在使用seqList.add()时出现错误
错误:未解析的引用:添加
我已经在stackoverflow上读了一些关于Kotlin中2d数组的问题,但它们是关于不可调整大小的数组或者已经过时了
我看到Kotlin提供了许多用于实现集合的接口.它们列在此页面上.
我没有看到Kotlin提供的任何实现.
但是,我确实看到全局命名空间中有一些函数可以帮助我们创建这些集合的实例.例如,为了创建一个可变的数字列表,我们可能会说:
var numbers : MutableList<Int> = mutableListOf(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
要创建列表的只读视图,我们可能会说:
val readOnlyViewOfNumbers : List<Int> = numbers;
Run Code Online (Sandbox Code Playgroud)
或者,要创建一个只读的数字列表,我们可能会说:
val readOnlyListOfNumbers : List<Int> = listOf(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
要创建n项目列表并使用值初始化每个元素null,我们可能会说:
// Sorry, I forgot the function name for this one. It
// is not nullableListOf(...)
val numbers : List<Int> = nullableListOf(n);
Run Code Online (Sandbox Code Playgroud)
要创建一个数组,比如说,对于数组的每个元素都有5个带有初始化函数的元素,我们可能会说:
val myArray : Array<Int> = Array(5, (i) => { /* return whatever */ };
Run Code Online (Sandbox Code Playgroud)
但是,如果我想创建一个List<Book>没有任何书籍,但我只想像这样初始化它(Java或C#代码):
List<Book> books = new ArrayList<Book>(); // Java …Run Code Online (Sandbox Code Playgroud) 我问了一个问题,如何设计一个复杂的课程,在Kotlin将来可以轻松地扩展一些课程?关于如何设计一个复杂的类,其中包含一些类,以便将来在Kotlin中轻松扩展.
名为s1m0nw1的专家给出了一个很好的答案,如下面的代码.
但我不知道他为什么要换MutableList到List在https://stackoverflow.com/posts/47960036/revisions,我能得到正确的结果,当我使用MutableList.你可以告诉我吗?
代码
interface DeviceDef
data class BluetoothDef(val Status: Boolean = false) : DeviceDef
data class WiFiDef(val Name: String, val Status: Boolean = false) : DeviceDef
data class ScreenDef(val Name: String, val size: Long) : DeviceDef
class MDetail(val _id: Long, val devices: List<DeviceDef>) {
inline fun <reified T> getDevice(): T {
return devices.filterIsInstance(T::class.java).first()
}
}
Run Code Online (Sandbox Code Playgroud)
添加
我认为这mutableListOf<DeviceDef>比ListOf<DeviceDef>将来扩展要好.
aMutableList.add()当我追加新的元素时,我可以使用函数来扩展 mutableListOf<DeviceDef>.
如果我使用ListOf<DeviceDef>,我必须用listOf(mBluetoothDef1, mWiFiDef1, //mOther) …
kotlin ×13
java ×4
collections ×3
immutability ×2
java-8 ×2
arraylist ×1
arrays ×1
c# ×1
data-class ×1
java-stream ×1