Android SparseArray值比较

Dis*_*lee 5 java android android-sparsearray

所以我写了一些非常简单的代码,发现了一个非常意外的行为。所有ListMap实现都使用equals节点的方法进行比较。因此,如果您有一个字符串列表,并且尝试获取列表中字符串的索引,则无需使用同一对象。例:

List<String> list = new ArrayList<>();
list.add("test");
int index = list.indexOf("test");
System.out.println(index);//returns 0
Run Code Online (Sandbox Code Playgroud)

我注意到,Android的所有SparseArray类都使用==而不是equals比较节点。示例方法(LongSparseArray.java):

public int indexOfValue(E value) {
    if (mGarbage) {
    gc();
    }

for (int i = 0; i < mSize; i++) {
    if (mValues[i] == value) {
        return i;
        }
    }
        return -1;
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您有这样的简单代码:

LongSparseArray<String> localContacts = new LongSparseArray<>();
localContacts.put(2, "test");
int index = localContacts.indexOfValue("test");
System.out.println(index);
Run Code Online (Sandbox Code Playgroud)

此处的索引将返回-1(如果不比较该值,这是非常意外的)。

所以我想知道...为什么Android不使用equals?从Java的角度来看,这是更方便和首选的方式。现在,我必须遍历a的所有值SparseArray并将其与我的自身进行比较,这将导致更多(不需要的)代码(或使用a Map会导致Android性能降低)。

PPa*_*san 2

查看 的源代码LongSparseArray,似乎该方法确实存在 - 但它是隐藏的(由于某种原因):

/**
* Returns an index for which {@link #valueAt} would return the
* specified key, or a negative number if no keys map to the
* specified value.
* <p>Beware that this is a linear search, unlike lookups by key,
* and that multiple keys can map to the same value and this will
* find only one of them.
* <p>Note also that this method uses {@code equals} unlike {@code indexOfValue}.
* @hide
*/
public int indexOfValueByValue(E value) {
    if (mGarbage) {
        gc();
    }

    for (int i = 0; i < mSize; i++) {
        if (value == null) {
            if (mValues[i] == null) {
                return i;
            }
        } else {
            if (value.equals(mValues[i])) {
                return i;
            }
        }
    }
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

您可以看到,所有这些代码实际上所做的就是您在问题中所说的 - 循环遍历所有值,直到找到正确的值,然后返回其索引。

我不知道为什么它被排除在公共 API 之外,但Sparse***在我看来,这是反对使用任何东西的另一点。它们通常太基础,无法满足我的要求。