Domanda

I am trying to iterate through a SparseArray and delete a few items.

private SparseArray record;

   int size = record.size();
        for (int index = 0; index < size; index++) {
            if (record.valueAt(index) < threshold){
                record.delete(record.keyAt(index));
            }
        }

But if I remove items midway through iteration, the size will change, So I cannot use this. I tried to clone the sparse array beforehand. But eclipse gives me error

The method clone() from the type object is not visible

But both api doc and Source code of SparseArray indicate it is present and public. Also the method clone has an annotation @SuppressWarnings("unchecked")

Does suppressing change the visibility of method?
Anyone has a clue how to solve this or clone the SparseArray?

È stato utile?

Soluzione

According to the Android API changes for SDK 14, we find that SparseArray was modified to include a public clone.

Edit

In my project, I implemented my own clone code for SB array: Source code here

Altri suggerimenti

Why don't you get the size of the array like this? or just use size-- whenever you delete a record?

    for (int index = 0; index < record.size(); index++) {
        if (record.valueAt(index) < threshold){
            record.delete(record.keyAt(index));
            index--;
        }
    }

FYI in support-v4, SparseArrayCompat is available to address this issue and more:

http://developer.android.com/reference/android/support/v4/util/SparseArrayCompat.html

Clone Method is protected for Object class so any class has to explicitly provide it but however I see this method in the documentation and Not in the source code. Seems that My API Level is 10 and docs API level is 16. So please check your API Level first.

@SuppressWarnings("unchecked") is because Clone method of Object returns Object where as from doc it seems that it returns SparseArray<E> which results in unsafe cast inside method to convert Object to SparseArray<E>

Still the clone is not updated in the API in Android docs nor it show any warning in compiling with API 9

So I wrote my own code for cloning the object

public static SparseBooleanArray getClone(SparseBooleanArray sparseBooleanArray) {
    if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH)
        return sparseBooleanArray.clone();
    return getCloneof(sparseBooleanArray);
}

private static SparseBooleanArray getCloneof(SparseBooleanArray sparseBooleanArray) {

    SparseBooleanArray temp = new SparseBooleanArray();
    try {
        int[] mKeys;
        boolean[] mValues;
        int mSize;
        Field mKeysField = sparseBooleanArray.getClass().getDeclaredField("mKeys");
        Field mValuesField = sparseBooleanArray.getClass().getDeclaredField("mValues");
        Field mSizeField = sparseBooleanArray.getClass().getDeclaredField("mSize");

        mKeysField.setAccessible(true);
        mValuesField.setAccessible(true);
        mSizeField.setAccessible(true);

        mKeys = (int[]) mKeysField.get(sparseBooleanArray);
        mValues = (boolean[]) mValuesField.get(sparseBooleanArray);
        mSize = (int) mSizeField.getInt(sparseBooleanArray);

        Field mKeysFieldtemp = temp.getClass().getDeclaredField("mKeys");
        Field mValuesFieldtemp = temp.getClass().getDeclaredField("mValues");
        Field mSizeFieldtemp = temp.getClass().getDeclaredField("mSize");

        mKeysFieldtemp.setAccessible(true);
        mValuesFieldtemp.setAccessible(true);
        mSizeFieldtemp.setAccessible(true);

        mKeysFieldtemp.set(temp, mKeys);
        mValuesFieldtemp.set(temp, mValues);
        mSizeFieldtemp.setInt(temp, mSize);

    } catch (Exception e) {
        e.printStackTrace();
    }
    return temp;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top