Android开发中如何通过坐标或名称双索引快速存取View结构
Android库双索引查询View的简单实现方案
核心实现思路
直接维护两个独立的HashMap分别处理两种查询逻辑,不需要自定义任何中间Key类,查询复杂度均为O(1),完全满足你要求的调用方式:
- 第一个Map处理坐标到View的映射
- 第二个Map处理cellName到View的映射
- 所有写入/删除操作同时操作两个Map,保证数据一致性
注意:不要用
Integer[]数组作为Map的key,Java中数组的equals方法比较的是内存地址而非内容,你新建的new[]{x,y}和存入时的数组不是同一个实例,会直接查询失败。
方案1:long拼接坐标作为key(推荐,性能最优)
利用int占32位的特性,把x、y两个int拼接成一个long作为坐标Map的key,不需要依赖任何额外类,性能最高:
import android.view.View; import java.util.HashMap; import java.util.Map; public class CellManager { private final Map<Long, View> coordinateMap = new HashMap<>(); private final Map<String, View> nameMap = new HashMap<>(); // 添加单元格 public void addCell(int xIndex, int yIndex, String cellName, View cellView) { if (cellName == null || cellView == null) { throw new IllegalArgumentException("cellName和cellView不能为null"); } // 拼接x、y为long类型key long coordinateKey = ((long) xIndex << 32) | (yIndex & 0xFFFFFFFFL); coordinateMap.put(coordinateKey, cellView); nameMap.put(cellName, cellView); } // 按坐标查询 public View getCell(int xIndex, int yIndex) { long coordinateKey = ((long) xIndex << 32) | (yIndex & 0xFFFFFFFFL); return coordinateMap.get(coordinateKey); } // 按名称查询 public View getByName(String cellName) { return nameMap.get(cellName); } // 移除单元格 public void removeCell(int xIndex, int yIndex, String cellName) { long coordinateKey = ((long) xIndex << 32) | (yIndex & 0xFFFFFFFFL); coordinateMap.remove(coordinateKey); nameMap.remove(cellName); } // 清空所有数据 public void clear() { coordinateMap.clear(); nameMap.clear(); } }
调用方式和你要求的完全一致:
View view1 = manager.getCell(2, 3); View view2 = manager.getByName("username_cell");
方案2:使用Android SDK自带Pair作为key(可读性更佳)
如果觉得拼接long的可读性不好,可以用Android原生提供的android.util.Pair类,它已经重写了equals和hashCode方法,不需要自己实现中间类:
import android.util.Pair; import android.view.View; import java.util.HashMap; import java.util.Map; public class CellManager { private final Map<Pair<Integer, Integer>, View> coordinateMap = new HashMap<>(); private final Map<String, View> nameMap = new HashMap<>(); public void addCell(int xIndex, int yIndex, String cellName, View cellView) { if (cellName == null || cellView == null) { throw new IllegalArgumentException("cellName和cellView不能为null"); } coordinateMap.put(Pair.create(xIndex, yIndex), cellView); nameMap.put(cellName, cellView); } public View getCell(int xIndex, int yIndex) { return coordinateMap.get(Pair.create(xIndex, yIndex)); } // getByName、remove、clear方法和方案1完全一致 public View getByName(String cellName) { return nameMap.get(cellName); } }
注意事项
- 如果业务允许同一个View对应多个坐标/多个名称,可以直接在add方法里重复写入即可,不需要修改底层结构
- 如果需要避免cellName重复,可在add方法里提前判断
nameMap.containsKey(cellName)再做相应处理 - 两种方案都没有额外依赖,代码量极小,完全符合你要的轻量化实现要求
内容的提问来源于stack exchange,提问作者pnet_fabric
相关产品推荐
相关产品推荐

