Java如何统一传感器数据列表大小?解决越界与并发修改异常
解决传感器数据列表长度不一致导致的数组越界与并发修改异常
一、先解决数组越界问题
你的第一段代码用acceleroElaps.size()作为循环上限,但其他列表可能更短,直接调用get(i)必然触发越界。正确做法是取所有相关列表的最小长度作为循环终止条件,确保不会访问到任何列表的不存在元素:
// 计算所有列表的最小长度 int minSize = Math.min(acceleroTime.size(), Math.min(acceleroElaps.size(), Math.min(acceleroXval.size(), Math.min(acceleroYval.size(), acceleroZval.size())))); List<HashMap<String, Object>> accelData = new ArrayList<>(); for (int i = 0; i < minSize; i++) { HashMap<String, Object> data = new HashMap<>(); data.put("person", "Adi"); data.put("tool", "Accelerometer"); data.put("time", acceleroTime.get(i)); data.put("elapsed", acceleroElaps.get(i)); data.put("xaxis", acceleroXval.get(i)); data.put("yaxis", acceleroYval.get(i)); data.put("zaxis", acceleroZval.get(i)); accelData.add(data); }
二、解决ConcurrentModificationException
这个异常通常是因为遍历列表时,其他线程修改了列表,或者当前线程用非迭代器方法(比如add/remove)修改了列表。可以用以下几种方式解决:
1. 确保遍历期间列表不被修改
检查代码逻辑,确认执行这段遍历操作时,没有其他线程在修改acceleroTime、acceleroElaps等列表;同时当前线程也不要在循环内对这些列表做增删操作。
2. 使用线程安全集合
如果是多线程场景,把这些列表换成CopyOnWriteArrayList,它的迭代器基于列表快照,遍历期间即使原列表被修改也不会抛出异常:
// 初始化列表时使用线程安全的实现 List<String> acceleroTime = new CopyOnWriteArrayList<>(); // 其他传感器数据列表同理
3. 遍历前拷贝列表
如果不想替换集合类型,可以在遍历前先拷贝每个列表,遍历拷贝后的副本,原列表的修改不会影响遍历过程:
// 先拷贝所有传感器数据列表 List<String> timeCopy = new ArrayList<>(acceleroTime); List<String> elapsCopy = new ArrayList<>(acceleroElaps); List<String> xvalCopy = new ArrayList<>(acceleroXval); List<String> yvalCopy = new ArrayList<>(acceleroYval); List<String> zvalCopy = new ArrayList<>(acceleroZval); // 计算拷贝后列表的最小长度 int minSize = Math.min(timeCopy.size(), Math.min(elapsCopy.size(), Math.min(xvalCopy.size(), Math.min(yvalCopy.size(), zvalCopy.size())))); List<HashMap<String, Object>> accelData = new ArrayList<>(); for (int i = 0; i < minSize; i++) { HashMap<String, Object> data = new HashMap<>(); data.put("person", "Adi"); data.put("tool", "Accelerometer"); data.put("time", timeCopy.get(i)); data.put("elapsed", elapsCopy.get(i)); data.put("xaxis", xvalCopy.get(i)); data.put("yaxis", yvalCopy.get(i)); data.put("zaxis", zvalCopy.get(i)); accelData.add(data); }
三、从根源避免问题
最彻底的方式是在传感器数据采集阶段保证同步:每次采集加速度计的time、elapsed、x/y/z轴数据时,确保这几组数据属于同一时刻,并且同时添加到对应的列表中。这样所有列表的长度自然一致,从根源上杜绝越界问题。
内容的提问来源于stack exchange,提问作者A Koirul Anwar
相关产品推荐
相关产品推荐

