BUG 关于iterator遍历JSONArray

本文探讨了使用Java遍历JSONArray并将其元素转换为特定Java对象的过程。重点关注如何正确地将Iterator返回的对象转换为HighwayVehicleDto实例,而不是尝试将其作为JSONObject处理。通过对比不同遍历方式的效果,说明了直接使用对应的数据类进行转换更为有效。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用iterator遍历jsonArray时
Iterator iterator=jsonArr.iterator();
while(iterator.hasNext()){
HighwayVehicleDto jo=(HighwayVehicleDto) iterator.next();
if(VehicleLicenseColor.parse(param.getVehicleColor()).getTitle().equals(jo.getLicenseColor())){
return buildRes(param, ResultStatus.SUCCESS.getValue());
}
}
当用JSONObject 去强转iterator.next()的对象是会报错,用之前转成JSONArray的数据类去接收就没问题
数据流程:
List —->jsonarray——>Iterator<默认类型就是HighwayVehicleDto>—->HighwayVehicleDto
Iterator—->JSONObject 是会转化失败的

用下面的方式遍历时转化是成功的
for(Object obj:jsonarray){
JSONObject json=(JSONObject)obj;
//do other things
}

解读代码:private void generatePushTask() throws InterruptedException, ExecutionException { Latency latency = MetricManager.INSTANCE.getOrRegisterLatency("stat.task.fw.generate", statsDuration); long start = System.nanoTime(); oaTaskLogger.info("#### scan and generate PushAppTask/PushDeviceTask Task ..."); // Regular fw, single thread for now Map<MatchCondition, TaskHandler<DeviceFwInfo>> regularFwTaskMap = new HashMap<>(); // Smb device firmwares, single thread for now Map<MatchCondition, TaskHandler<DeviceFwInfo>> smbFwTaskMap = new HashMap<>(); // FAP device firmwares, single thread for now Map<MatchCondition, TaskHandler<DeviceFwInfo>> FAPFwTaskMap = new HashMap<>(); //dst zoneId:DstRulePushTask, single thread for now Map<String, TaskHandler<DeviceConfigInfo>> dstRulePushTaskMap = new HashMap<>(); //signature, single thread for now Map<SigMatchCondition, TaskHandler<DeviceInfo>> m5SignaturePushTaskMap = new HashMap<>(); //由于是底层数据源是mysql,返回结果默认按照主键task_id升序排列,因此list中oa_task_id由小到大,for遍历时task_id大的任务也 //加入在fwHandlerList的后面,在遍历fwHandlerList时,task_id较大的任务较后处理,在updatePushTaskStatus时可以将前面task_id //较小的任务生成的push_device_task失效掉,保证读取到的任务中最后发布的被推送 //添加排序,保证taskList内部task按照task_id升序排列 List<FwReleaseTask> fwReleaseList = new ArrayList<>(); if (IS_FW_TASK_ENABLED) { //smb设备、正式固件(FAP推送、一般设备推送) fwReleaseList = pushDAO.findFwTaskInRDB(TaskStatusCode.READY, CURRENT_REGION, "N"); } //过滤下架任务 //BugFix:修复使用arrayList.remove造成的ConcurrentModificationException Iterator<FwReleaseTask> iterator = fwReleaseList.iterator(); FwReleaseTask fwReleaseTask; while (iterator.hasNext()) { fwReleaseTask = iterator.next(); if(ONSHELF_OFF.equalsIgnoreCase(fwReleaseTask.getOnShelf())){ iterator.remove(); } } Collections.sort(fwReleaseList); //目前eap设备暂无beta固件推送 for (FwReleaseTask task : fwReleaseList) { //将where为空的任务置为失效 if (Objects.equals(task.getWhere(), "[]")) { task.setStatusCode(TaskStatusCode.DISABLE); logger.warn("disable meaningless fw_release_task,task={}", task); pushDAO.saveOrUpdateInRDB(task); latency.record(System.nanoTime() - start, ErrorCause.BIZ); continue; } try { if (eapDeviceList.contains(task.getDeviceCategory())) {//EAP设备 oaTaskLogger.info("[generate] load fw_release_task for eap device,[task={}]", task); FwReleaseTaskHandler handler = new FwReleaseTaskHandler(task, pushDAO, authService, isPushEapAppEnabled, statsDuration, appFwFilterMap, oaQueue, true, vigiEnabled, batchSender, senderMap, grpcClient, databaseSwitch, deviceUserService); PushUtil.generateTaskMapByStr(smbFwTaskMap, task.getWhere(), handler, CURRENT_REGION); } else if (apDeviceList.contains(task.getDeviceCategory())) {//AP设备,需要给订阅ap设备的主设备发送推送 oaTaskLogger.info("[generate] load fw_release_task for ap device,[task={}]", task); FwReleaseFAPDeviceTaskHandler fapHandler = new FwReleaseFAPDeviceTaskHandler(task, pushDAO, authService, statsDuration, batchSender); PushUtil.generateTaskMapByStr(FAPFwTaskMap, task.getWhere(), fapHandler, CURRENT_REGION); oaTaskLogger.info("[generate] load fw_release_task for regular device,[task={}]", task); FwReleaseTaskHandler handler = new FwReleaseTaskHandler(task, pushDAO, authService, true, statsDuration, appFwFilterMap, oaQueue, true, vigiEnabled, batchSender, senderMap, grpcClient, databaseSwitch, deviceUserService); PushUtil.generateTaskMapByStr(regularFwTaskMap, task.getWhere(), handler, CURRENT_REGION); } else {//一般设备 oaTaskLogger.info("[generate] load fw_release_task for regular device,[task={}]", task); FwReleaseTaskHandler handler = new FwReleaseTaskHandler(task, pushDAO, authService, true, statsDuration, appFwFilterMap, oaQueue, true, vigiEnabled, batchSender, senderMap, grpcClient, databaseSwitch, deviceUserService); PushUtil.generateTaskMapByStr(regularFwTaskMap, task.getWhere(), handler, CURRENT_REGION); } latency.recordSuccess(System.nanoTime() - start); } catch (Exception e) { task.setStatusCode(TaskStatusCode.DISABLE); pushDAO.saveOrUpdateInRDB(task); latency.record(System.nanoTime() - start, ErrorCause.BIZ); logger.error("fw_release_task ERROR:task illegal,task={}", task, e); } } // 删除对应hardwareId, oemId的首次上线推送的缓存 if (regularFwTaskMap.size() > 0) { regularFwTaskMap.keySet().forEach(matchCondition -> pushDAO .delFwTaskCache(matchCondition.getHardwareId(), matchCondition.getOemId(), false)); } if (FAPFwTaskMap.size() > 0) { FAPFwTaskMap.keySet().forEach(matchCondition -> pushDAO .delFwTaskCache(matchCondition.getHardwareId(), matchCondition.getOemId(), false)); } if (smbFwTaskMap.size() > 0) { smbFwTaskMap.keySet().forEach(matchCondition -> pushDAO .delFwTaskCache(matchCondition.getHardwareId(), matchCondition.getOemId(), false)); } // dst //添加排序,保证taskList内部task按照task_id升序排列 List<DstRulePushTask> dstTaskList = new ArrayList<>(); if (IS_DST_TASK_ENABLED) { //dst任务 dstTaskList = pushDAO.findOATaskByStatusInRDB(DstRulePushTask.class, TaskStatusCode.READY, CURRENT_REGION); } Collections.sort(dstTaskList); for (DstRulePushTask task : dstTaskList) { DstRulePushTaskHandler handler = new DstRulePushTaskHandler(task, pushDAO, statsDuration, dstQueue, batchSender); oaTaskLogger.info("[generate] load DST release task,[task={}]", task); dstRulePushTaskMap.put(task.getZoneId(), handler); } // signature List<M5SignaturePushTask> m5SigTaskList = new ArrayList<>(); if (IS_M5_TASK_ENABLED) {//m5任务 m5SigTaskList = pushDAO.findOATaskByStatusInRDB(M5SignaturePushTask.class, TaskStatusCode.READY, CURRENT_REGION); } Collections.sort(m5SigTaskList); for (M5SignaturePushTask task : m5SigTaskList) { List<SignatureSuitableModel> ssms = pushDAO.getSignatureSuitableModels(task.getSigVersion()); JSONArray whereJson = new JSONArray(); if (ssms != null) { for (SignatureSuitableModel ssmInfo : ssms) { JSONObject obj = new JSONObject(); obj.put(Constants.FIRMWARE_VERSION, ssmInfo.getFirmwareVersion()); obj.put(Constants.HARDWARE_ID, ssmInfo.getHwId()); obj.put(Constants.OEM_ID, ssmInfo.getOemId()); whereJson.put(obj); } } else { logger.info("Signature Version={} has no upgrade relationship", task.getSigVersion()); continue; } M5SignaturePushTaskHandler handler = new M5SignaturePushTaskHandler(task, pushDAO, statsDuration, oaQueue); oaTaskLogger.info("[generate] load signature release task,[task={}]", task); if (whereJson.length() > 0) { PushUtil.generateSigTaskMapByJson(m5SignaturePushTaskMap, whereJson, handler, CURRENT_REGION); } } // first check whether loop is necessary, then generate push task // 1. loop devices if (regularFwTaskMap.size() + m5SignaturePushTaskMap.size() != 0) { logger.info("begin loop devices for regular fw and M5 sig, fwMap={}, m5Map={}", regularFwTaskMap, m5SignaturePushTaskMap); long step1 = MAX_TOKEN / SPLIT_SIZE; long step2 = MIN_TOKEN / SPLIT_SIZE; long step = step1 - step2; long totalDeviceNum = 0; long index = 0; int mapSize = (int) (0.2 * EXECUTOR_QUEUE_SIZE); logger.info("start split and handle devices,[min={},max={},size={},step={},mapSize={}]", MIN_TOKEN, MAX_TOKEN, SPLIT_SIZE, step, mapSize); Map<Long, Future<Long>> futureMap = new HashMap<>(); while (index < SPLIT_SIZE) { Thread.sleep(TASK_SLEEP_MS); if (futureMap.size() < mapSize) { //TODO:一次添加多个 long lower = MIN_TOKEN + index * step; long upper; if (index == SPLIT_SIZE - 1) { upper = MAX_TOKEN; } else { upper = lower + step > MAX_TOKEN ? MAX_TOKEN : lower + step; } logger.info("add new period to execute,[index={},lower={},upper={}]", index, lower, upper); Future<Long> future = executor.submit(() -> { long deviceCount = 0; int retry = 0; while (retry < FW_TASK_RETRY_LIMIT) { if (retry > 0) { Thread.sleep((long) Math.pow(2, retry) * 1000); } try { deviceCount = handleDeviceTask(lower, upper, regularFwTaskMap, m5SignaturePushTaskMap); break; } catch (Exception e) { logger.error("handle device task error,[lower={},upper={},retry={}]", lower, upper, retry, e); retry = retry + 1; } } if (retry >= FW_TASK_RETRY_LIMIT) { logger.error("failed to handle device task,[lower={},upper={},retry={}]", lower, upper, retry); } else { logger.info("success handle device task,[lower={},upper={},retry={}]", lower, upper, retry); } return deviceCount; }); futureMap.put(index, future); logger.info("add future to map,[index={},map={}]", index, futureMap); index = index + 1; } Iterator<Long> futureInterator = futureMap.keySet().iterator(); while (futureInterator.hasNext()) { Long key = futureInterator.next(); Future<Long> future = futureMap.get(key); if (future.isDone()) { futureInterator.remove(); long count = future.get(); totalDeviceNum = totalDeviceNum + count; logger.info("work done,[index={},count={},total={}]", key, count, totalDeviceNum); } } } while (!futureMap.isEmpty()) { //noinspection BusyWait Thread.sleep(TASK_SLEEP_MS); Iterator<Long> futureInterator = futureMap.keySet().iterator(); while (futureInterator.hasNext()) { Long key = futureInterator.next(); Future<Long> future = futureMap.get(key); if (future.isDone()) { futureInterator.remove(); long count = future.get(); totalDeviceNum = totalDeviceNum + count; logger.info("work done,[index={},count={},total={}]", key, count, totalDeviceNum); } } } logger.info("end split and handle devices,totalDeviceNum={},deviceNotifyNum={},appNotifyNum={}", totalDeviceNum, totalDeviceSet.size(), totalAppSet.size()); totalAppSet.clear(); totalDeviceSet.clear(); } // 2. loop device_config try { if (dstRulePushTaskMap.size() != 0) { logger.info("begin loop deviceConfigInfos for dst task, dstTaskMap={}", dstRulePushTaskMap); Iterable<DeviceConfigInfo> deviceConfigInfos = pushDAO.getAllDeviceConfigInfo(); //数据分区隔离开关 if (DATA_BASE_PARTITION_ENABLED) { for (DeviceConfigInfo deviceConfigInfo : deviceConfigInfos) { if ((dstRulePushTaskMap.get(deviceConfigInfo.getZoneId()) != null)) { //打开设备区域检查开关后,调用grpc接口判断本区是否为设备的存储区,并统计通过storage区域检查的设备数量 if (NEED_CHECK_DEVICE_STORAGE_REGION) { DeviceRegionInfoList deviceRegionInfo = grpcClient .getDeviceRegionInfo(deviceConfigInfo.getDeviceId()); if (Objects.isNull(deviceRegionInfo)) { continue; } String connectRegion = deviceRegionInfo.getConnectRegion(); String storageRegion = deviceRegionInfo.getStorageRegion(); if (CURRENT_REGION.equals(storageRegion)) { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_DST_RULE_TASK_DEVICE_REGION_MATCH).inc(); dstRulePushTaskMap.get(deviceConfigInfo.getZoneId()) .handle(deviceConfigInfo, pushDeviceTaskMap, null, null, null, connectRegion); } else { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_DST_RULE_TASK_DEVICE_REGION_MATCH_ERROR).inc(); } } else { dstRulePushTaskMap.get(deviceConfigInfo.getZoneId()) .handle(deviceConfigInfo, pushDeviceTaskMap, null, null, null, null); } } } } else { for (DeviceConfigInfo deviceConfigInfo : deviceConfigInfos) { if (dstRulePushTaskMap.get(deviceConfigInfo.getZoneId()) != null) { dstRulePushTaskMap.get(deviceConfigInfo.getZoneId()) .handle(deviceConfigInfo, pushDeviceTaskMap, null, null, null, null); } } } } } catch (Exception e) { logger.error("loop device_config failed", e); dstRulePushTaskMap.clear(); } // 3. loop eap devices if (smbFwTaskMap.size() != 0) { logger.info("begin loop eapDevices for eapFwtasks, taskMap={}", smbFwTaskMap); Iterable<EapDeviceInfo> eapDevices = pushDAO.getAllEapDeviceInfo(); //数据分区隔离开关 if (DATA_BASE_PARTITION_ENABLED) { for (EapDeviceInfo eapDeviceInfo : eapDevices) { if ((smbFwTaskMap.get(eapDeviceInfo.toMatchConditionLocalRegion(CURRENT_REGION)) != null)) { //打开设备区域检查开关后,调用grpc接口判断本区是否为设备的存储区,并统计通过storage区域检查的设备数量 if (NEED_CHECK_DEVICE_STORAGE_REGION) { DeviceRegionInfoList deviceRegionInfo = grpcClient .getDeviceRegionInfo(eapDeviceInfo.getDeviceId()); if (Objects.isNull(deviceRegionInfo)) { continue; } String connectRegion = deviceRegionInfo.getConnectRegion(); String storageRegion = deviceRegionInfo.getStorageRegion(); if (CURRENT_REGION.equals(storageRegion)) { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_SMB_FW_TASK_DEVICE_REGION_MATCH).inc(); smbFwTaskMap.get(eapDeviceInfo.toMatchConditionLocalRegion(CURRENT_REGION)) .handle(eapDeviceInfo.toDeviceFwInfo(), pushDeviceTaskMap, pushAppTaskMap, totalSMBDeviceSet, totalSMBAppSet, connectRegion); } else { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_SMB_FW_TASK_DEVICE_REGION_MATCH_ERROR).inc(); } } else { smbFwTaskMap.get(eapDeviceInfo.toMatchConditionLocalRegion(CURRENT_REGION)) .handle(eapDeviceInfo.toDeviceFwInfo(), pushDeviceTaskMap, pushAppTaskMap, totalSMBDeviceSet, totalSMBAppSet, null); } } } } else { //原逻辑,保留便于回滚 for (EapDeviceInfo eapDeviceInfo : eapDevices) { if (smbFwTaskMap.get(eapDeviceInfo.toMatchCondition()) != null) { smbFwTaskMap.get(eapDeviceInfo.toMatchCondition()) .handle(eapDeviceInfo.toDeviceFwInfo(), pushDeviceTaskMap, pushAppTaskMap, totalSMBDeviceSet, totalSMBAppSet, null); } } } logger.info("begin loop eapDevices for eap tasks, deviceNum={}, appNum={}, taskMap={}", totalSMBDeviceSet.size(), totalSMBAppSet.size(), smbFwTaskMap); } totalSMBDeviceSet.clear(); totalSMBAppSet.clear(); //4. loop ap devices(using PushSubscriptionDevice) if (FAPFwTaskMap.size() != 0) { logger.info("begin loop apDevices for FAPFwtasks, taskMap={}", FAPFwTaskMap); Iterable<PushSubscriptionDevice> pushSubscriptionDevices = pushDAO.getAllPushSubscriptionDevice(); //数据分区隔离开关 if (DATA_BASE_PARTITION_ENABLED) { //调用grpc接口判断本区是否为设备的存储区 for (PushSubscriptionDevice subscriptionDevice : pushSubscriptionDevices) { if ((FAPFwTaskMap.get(subscriptionDevice.toMatchConditionLocalRegion(CURRENT_REGION)) != null)) { //调用grpc接口判断本区是否为设备的存储区,并统计通过storage区域检查的设备数量 Latency latencyCheckDevice = MetricManager.INSTANCE.getOrRegisterLatency( "stat.generate_task_fap_fw_task_check_device_storage_region", statsDuration); DeviceRegionInfoList deviceRegionInfo = grpcClient .getDeviceRegionInfo(subscriptionDevice.getSubscriber()); if (Objects.isNull(deviceRegionInfo)) { continue; } String connectRegion = deviceRegionInfo.getConnectRegion(); String storageRegion = deviceRegionInfo.getStorageRegion(); if (CURRENT_REGION.equals(storageRegion)) { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_FAP_FW_TASK_DEVICE_REGION_MATCH).inc(); FAPFwTaskMap.get(subscriptionDevice.toMatchConditionLocalRegion(CURRENT_REGION)) .handle(subscriptionDevice.toDeviceFwInfo(), FAPDeviceTaskMap, null, totalEAPDeviceSet, null, connectRegion); } else { MetricManager.INSTANCE.getOrRegisterCounter( Constants.ALL_STAT_FAP_FW_TASK_DEVICE_REGION_MATCH_ERROR).inc(); } } } } else { //原逻辑,保留便于回滚 for (PushSubscriptionDevice subscriptionDevice : pushSubscriptionDevices) { if (FAPFwTaskMap.get(subscriptionDevice.toMatchCondition()) != null) { FAPFwTaskMap.get(subscriptionDevice.toMatchCondition()) .handle(subscriptionDevice.toDeviceFwInfo(), FAPDeviceTaskMap, null, totalEAPDeviceSet, null, null); } } } logger.info("end loop apDevices for FAP task, num={}, taskMap={}", totalEAPDeviceSet.size(), FAPFwTaskMap); } totalEAPDeviceSet.clear(); @SuppressWarnings("unchecked") Iterable<TaskHandler<?>> handlers = Iterables.concat(regularFwTaskMap.values(), m5SignaturePushTaskMap.values(), dstRulePushTaskMap.values(), smbFwTaskMap.values(), FAPFwTaskMap.values()); for (TaskHandler<?> handler : handlers) { handler.setHandling(); handlingList.add(handler); } regularFwTaskMap.clear(); m5SignaturePushTaskMap.clear(); dstRulePushTaskMap.clear(); smbFwTaskMap.clear(); FAPFwTaskMap.clear(); oaTaskLogger.info("[generate] add handling task.[handlingTask={}]", handlingList.toString()); handlingList.clear(); oaTaskLogger.info("[generate] generate push device task amount={}", pushDeviceTaskMap.size() + FAPDeviceTaskMap.size()); oaTaskLogger.info("[generate] generate push app task amount={}", pushAppTaskMap.size()); }
最新发布
06-17
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值