業務描述:根據 gameId serverId 兩個參數 獲取 serverName 。在遍歷時需要發送HTTP請求獲取。這時想要優化請求次數,便是對List分組。減少發送次數。
這裏使用了,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;
}
其實以上方法,是將簡單問題複雜化了。線上沒有使用這個方法。但是這裏的多條件分組,學習了。