代码之家  ›  专栏  ›  技术社区  ›  Bryan

SimpleArrayMap和ArrayMap是否意味着保留订单?

  •  1
  • Bryan  · 技术社区  · 8 年前

    我知道 SimpleArrayMap ArrayMap 类意味着更高效(对于少量项)替换 HashMap . 哈希图 没有可预测的迭代顺序(与 LinkedHashMap ),但我注意到 SimpleArrayMap 阵列地图 这些课程让我相信他们可能。

    keyAt(int index) , valueAt(int index) removeAt(int index) 似乎表明 SimpleArrayMap 阵列地图 以可预测的方式存储他们的项目。这些方法也使访问这些项目非常方便,因此我添加了 阵列地图 FragmentPagerAdapter 要保存每页的标题和片段:

    public class TabPagerAdapter extends FragmentPagerAdapter {
    
        private final ArrayMap<CharSequence, Fragment> mData = new ArrayMap();
    
        public TabPagerAdapter(FragmentManager manager) {
            super(manager);
        }
    
        public void addPage(CharSequence title, Fragment fragment) {
            mData.put(title, fragment);
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return mData.keyAt(position);
        }
    
        @Override
        public Fragment getItem(int position) {
            return mData.valueAt(position);
        }
    
        @Override
        public int getCount() {
            return mData.size();
        }
    
    }
    

    尽管我注意到,在实践中 getPageTitle() getItem() 不总是按照我将它们添加到 阵列地图 但是为什么这些类会有按索引返回键和值的方法(而不是只使用 Map#get(Object key) 方法)如果这些项目的指数不可预测?

    SimpleArrayMap 阵列地图 旨在保留订单?我做错什么了吗?或者,如果不是,为什么它们包含上述方法?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Mikael Ohlson    8 年前

    在查看SimpleArrayMap实现之后,当调用put、putAll或remove方法时,它似乎会动态地增长和收缩。此时,索引可能会更改。如果你打电话 notifyDataSetChanged() 在你的电话接通后,你可能会过得更好。现在,这只是我对你的代码的推理,所以没有保证。:)

    更仔细地看,indexOf方法需要搜索项目的假定索引,因为在缩小映射时,索引的键哈希的内部数组似乎不会更新。所以指数可以明显改变。

    int index = ContainerHelpers.binarySearch(mHashes, N, hash);
    
    // If the hash code wasn't found, then we have no entry for this key.
    if (index < 0) {
        return index;
    }
    
    // If the key at the returned index matches, that's what we want.
    if (key.equals(mArray[index<<1])) {
       return index;
    }
    
    // Search for a matching key after the index.
    int end;
    for (end = index + 1; end < N && mHashes[end] == hash; end++) {
        if (key.equals(mArray[end << 1])) return end;
    }
    
    // Search for a matching key before the index.
    for (int i = index - 1; i >= 0 && mHashes[i] == hash; i--) {
        if (key.equals(mArray[i << 1])) return i;
    }
    
    // Key not found -- return negative value indicating where a
    // new entry for this key should go.  We use the end of the
    // hash chain to reduce the number of array entries that will
    // need to be copied when inserting.
    return ~end;
    

    索引方法可能存在于您知道没有修改映射的情况下。

    更新: 为了实现您想要的功能,您需要实现 public long getItemId(int position) 同样,因为你的位置没有给你一个稳定的物品id。

    我想说,如果您希望对底层映射进行更改,那么使用索引方法可能不是最佳选择,因为缓存的索引必须更新。