业务描述:根据 gameId serverId 两个参数 获取 serverName 。在遍历时须要发送HTTP请求获取。这时想要优化请求次数,即是对List分组。减小发送次数。java
这里使用了,Stream 的 分组,这时是使用了两个条件gameId 和 serverId。缓存
final static Cache<String, String> SERVER_NAME_CACHE = CacheBuilder .newBuilder() // 设置cache的初始大小为20,要合理设置该值 根据分页数量 .initialCapacity(20) // 设置并发数为5,即同一时间最多只能有5个线程往cache执行写入操做 能够不设置 .concurrencyLevel(5) // 设置cache中的数据在写入以后的存活时间为10分钟 .expireAfterWrite(10, TimeUnit.MINUTES) // 构建cache实例 .build(); /** * 方法说明 : 根据游戏id 服务器id 获取服务请名称时 合并 请求 并缓存 */ private ConcurrentMap<String, String> mergeRequestWithServerName( List<WoWorkOrderVo> list) { ConcurrentMap<String, String> cacheMap = SERVER_NAME_CACHE.asMap(); // 根据 GameId ServerId 分组 Map<Integer, Map<Integer, List<WoWorkOrderVo>>> group = list .parallelStream() .collect(Collectors.groupingBy(WoWorkOrderVo::getGameId, Collectors.groupingBy(WoWorkOrderVo::getServerId))); // 组织 map k->gameId v->serverId Map<Integer, Integer> map = new IdentityHashMap<>(); Iterator<Entry<Integer, Map<Integer, List<WoWorkOrderVo>>>> itOut = group .entrySet().iterator(); // 遍历外层 while (itOut.hasNext()) { Entry<Integer, Map<Integer, List<WoWorkOrderVo>>> entry = itOut .next(); Integer keyOut = entry.getKey(); // 获取内层值 Map<Integer, List<WoWorkOrderVo>> value = entry.getValue(); // 遍历内层 Iterator<Entry<Integer, List<WoWorkOrderVo>>> itIn = value .entrySet().iterator(); while (itIn.hasNext()) { Entry<Integer, List<WoWorkOrderVo>> next = itIn.next(); Integer keyIn = next.getKey(); map.put(new Integer(keyOut), new Integer(keyIn)); } } ConcurrentMap<String, String> gameServerNameMap = new ConcurrentHashMap<>(); map.forEach((k, v) -> { if (StringUtils.isBlank(cacheMap.get(k + "&" + v))) { gameServerNameMap.put(k + "&" + v, agentService.getGameServerName(k, v)); SERVER_NAME_CACHE.put(k + "&" + v, agentService.getGameServerName(k, v)); } }); LOGGER.info("【SERVER_NAME_CACHE 缓存MAP的信息{}】", cacheMap.toString()); return cacheMap.isEmpty() ? gameServerNameMap : cacheMap; }
其实以上方法,是将简单问题复杂化了。线上没有使用这个方法。可是这里的多条件分组,学习了。服务器