在Kotlin中检查ArrayList的类型

10

Kotlin提供了Array.isArrayOf()方法,用于检查数组是否为特定类型。

它的使用方式如下:

if(object.isArrayOf<String>())

定义如下:

/**
 * Checks if array can contain element of type [T].
 */
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
public fun <reified T : Any> Array<*>.isArrayOf(): Boolean =
    T::class.java.isAssignableFrom(this::class.java.componentType)

但它仅适用于数组。我需要检查ArrayList。

我考虑将签名更改为以下内容。

@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
public fun <reified T : Any> ArrayList<*>.isArrayListOf(): Boolean =
    T::class.java.isAssignableFrom(this::class.java.componentType)

但是 class.java.componentType 只适用于数组。

如何检查我有哪种类型的 ArrayList?

我应该澄清,我只关心它是否属于三种类型之一,所以我不需要完全开放的检查方式。


你为什么要使用ArrayList进行检查?这不是基本实现。 - Zoe stands with Ukraine
我需要将它直接传递到适当的Bundle方法中。bundle.putStringArrayList(),bundle.putIntegerArrayList()等。 - lbenedetto
列表通常依赖于泛型。由于类型擦除,您无法检查它具有的泛型类型。 - Zoe stands with Ukraine
3个回答

6
如果您想检查列表的类型,可以执行以下操作:
when (list.firstOrNull()) {
   is String -> { /*do something*/ }
   is Int -> { /*do another thing*/ }
   else -> { /*do something else*/ }
}

如果你需要使用特定类型的列表,可以使用以下方法:

list.filterInstance</*the type you need*/>()

希望这对你有用。

4
你不能这样做。在所有泛型类型中,只有数组可以这样做(因为在同样的意义下它们并不是真正的泛型类型,Kotlin只是隐藏了这一点)。
你唯一能做的是查看它的内容,但当然,
  1. 对于空列表无法使用;
  2. 如果一个列表包含例如一个字符串(String),它可以是ArrayList,ArrayList,ArrayList等。
为此目的:

我需要将其导入适当的Bundle方法。bundle.putStringArrayList(),bundle.putIntegerArrayList()等都没有问题,我相信。


1
请解释一下这不是问题吗?我有一个对象,但我不知道它是Parcelable的ArrayList还是整数。我不能将一个传递给另一个。我知道它们最终都会以HashMap<String,Object>的形式出现,但我仍然需要调用正确的方法。 - lbenedetto
此外,如果它是一个ArrayList,其中包含无法放入Bundle中的内容,则会失败。 - lbenedetto
就像我之前所说的,检查一下内容。如果第一个元素是例如 Integer,则转换为 ArrayList<Int> 等等。如果列表为空,则无论你将其转换成什么类型都无所谓,因为所有的 put* 方法都只会存储长度为 0 的值。 - Alexey Romanov
实际上,在检查后,由于 Bundle.put* 方法根本不查看内容,只是将参数放入映射中,因此您也可以忽略它们,只需将其转换为 ArrayList<String>。我猜这可能会在将来的版本中有所改变。 - Alexey Romanov
是的,它将它们放在映射中,但在某个时候,它会将该映射写入某种字符串,以便可以存储在磁盘上。并且无论执行这个操作的是什么,可能都会关心它是其中一个有效类型。 - lbenedetto
是的,它必须是有效类型之一,但是哪种类型并不重要。也就是说,即使您的列表实际上包含整数,它也可以使用putStringArrayList(list as ArrayList<String>)放入bundle中,并正确地存储到Parcel中。如果您需要检查类型是否合法,则需要检查内容。严格来说,您必须检查列表中的所有项目,因为它始终可以是ArrayList<Any> - Alexey Romanov

0
如果列表只有一种类型,那么您可以使用toTypedArray()将列表转换为数组,然后可以使用isArrayOf检查类型。
但是这样做效率较低,因为您需要将列表转换为数组,最好的方法是直接猜测或检索列表的第一个项目。

我考虑获取第一个项目并检查,但是列表可能为空。 - lbenedetto
更大的问题是 toTypedArray 首先需要知道集合的类型。如果你有一个 ArrayList<*>,你只会得到 Array<Any> - Alexey Romanov

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