lamda list 分组_java8lambda表达式对集合分组并且排序(记一次性能优化案例)
最近遇到個(gè)需求是這樣的:
寫(xiě)一個(gè)類似于通訊錄的簡(jiǎn)單功能,要求是首先按照部門(mén)顯示列表,然后點(diǎn)擊部門(mén)下拉顯示部門(mén)里面的人員信息,且人員信息按照職位排序。
先分析數(shù)據(jù)結(jié)構(gòu):
最外層是部門(mén),部門(mén)里面是員工,且項(xiàng)目是統(tǒng)一返回?cái)?shù)據(jù)格式。
{
"code": 0,
"data": [
{
"name": "部門(mén)名稱",
"userData": [
{
"deptName": "部門(mén)名稱",
"info": "部門(mén)名稱+職位",
"phone": "電話號(hào)碼",
"userName": "員工姓名"
}
]
},
{
"name": "部門(mén)名稱",
"userData": [
{
"deptName": "部門(mén)名稱",
"info": "部門(mén)名稱+職位",
"phone": "電話號(hào)碼",
"userName": "員工姓名"
}
]
}
],
"message": "success"
}
數(shù)據(jù)格式大概就是這樣。然后分析寫(xiě)法。正常來(lái)說(shuō)需要用sql將這些數(shù)據(jù)一次性分組并返回出來(lái),本人沒(méi)有找到合適的方法。然后打算用最原始的方法,就是先查出所有的部門(mén),再遍歷部門(mén)查詢出部門(mén)里面所有的人員,再將數(shù)據(jù)返回。下面貼上代碼。
List deptAll = (List) dao.findForList("AddressListMapper.querydeptAll", pageData);
//創(chuàng)建list保存所有部門(mén)和部門(mén)人員
List deptPersonnelAll = new ArrayList();
//遍歷獲取到的部門(mén)查詢相對(duì)應(yīng)得人員信息
/*??????? for (HashMap dept : deptAll) {
//獲取部門(mén)名稱
String deptName = String.valueOf(dept.get("name"));
//獲取部門(mén)code
String deptCode = String.valueOf(dept.get("code"));
//根據(jù)部門(mén)code查詢部門(mén)對(duì)應(yīng)的人員
PageData pageDatap = new PageData();
pageDatap.put("deptid", deptCode);
ArrayList personnelList = queryPersonnel(pageDatap);
//將數(shù)據(jù)存封裝為map并存進(jìn)list
PageData deptSingle = new PageData();
deptSingle.put("name", deptName);
deptSingle.put("userData", personnelList);
deptPersonnelAll.add(deptSingle);
}*/
deptAll.stream().forEach(dept -> {
//獲取部門(mén)名稱
String deptName = String.valueOf(dept.get("name"));
//獲取部門(mén)code
String deptCode = String.valueOf(dept.get("code"));
//根據(jù)部門(mén)code查詢部門(mén)對(duì)應(yīng)的人員
PageData pageDatap = new PageData();
pageDatap.put("deptid", deptCode);
ArrayList personnelList = null;
try {
personnelList = queryPersonnel(pageDatap);
} catch (Exception e) {
e.printStackTrace();
}
//將數(shù)據(jù)存封裝為map并存進(jìn)list
PageData deptSingle = new PageData();
deptSingle.put("name", deptName);
deptSingle.put("userData", personnelList);
deptPersonnelAll.add(deptSingle);
});
return deptPersonnelAll;
上面遍歷集合寫(xiě)了兩種方式,一種是以前的for循環(huán)寫(xiě)法,另一種是用表達(dá)式。
但是這種方式會(huì)出現(xiàn)一個(gè)性能問(wèn)題,比如說(shuō)有10000個(gè)部門(mén),就需要查詢10000次數(shù)據(jù)庫(kù)。這樣會(huì)增大數(shù)據(jù)庫(kù)的壓力和查詢時(shí)間。所以這樣就需要優(yōu)化。
優(yōu)化:
優(yōu)化的方式就是在數(shù)據(jù)一次查出所有的人員信息,并將人員信息和部門(mén)信息進(jìn)行關(guān)聯(lián),這樣就能知道每個(gè)人所對(duì)應(yīng)的部門(mén)。然后用java代碼可以對(duì)數(shù)據(jù)進(jìn)行分組。
貼代碼:
public List> getAllPersonnel(PageData pageData) throws Exception {
//查詢類型對(duì)應(yīng)的人員
List addressList = (List) dao.findForList("AddressListMapper.getAllPersonnel", pageData);
//lambda表達(dá)式對(duì)數(shù)據(jù)進(jìn)行分組
Map> collect = addressList.stream().collect(Collectors.groupingBy(AddressList::getDeptName));
//處理分組后的數(shù)據(jù)
//創(chuàng)建一個(gè)list集合存儲(chǔ)所有數(shù)據(jù)
List> maps = new ArrayList<>();
//遍歷分組后的數(shù)據(jù),進(jìn)行組裝
collect.forEach((k, v) -> {
HashMap map = new HashMap<>();
map.put("name", k);
map.put("userData", v);
maps.add(map);
});
return maps;
}
這邊分組是用的表達(dá)式分組的,定義一個(gè)對(duì)象,將數(shù)據(jù)庫(kù)查出來(lái)的數(shù)據(jù)封裝進(jìn)去,然后按照屬性進(jìn)行分組。這樣就可以避免多次請(qǐng)求數(shù)據(jù)庫(kù)。
處理排序:
這樣優(yōu)化完后還有一個(gè)排序的問(wèn)題。
解決辦法:
上面代碼中g(shù)roupingBy有三個(gè)參數(shù)
第一個(gè)參數(shù):分組按照什么分類
第二個(gè)參數(shù):分組最后用什么容器保存返回值(默認(rèn)是HashMap::new)
第三個(gè)參數(shù):按照第一個(gè)參數(shù)分類后,對(duì)應(yīng)的分類的結(jié)果如何收集。(Collectors.toList)
這邊主要問(wèn)題是數(shù)據(jù)庫(kù)里面將數(shù)據(jù)排序好之后返回到代碼里面。代碼里面對(duì)數(shù)據(jù)進(jìn)行分組之后,數(shù)據(jù)的順序發(fā)生了改變。
map里面的有序集合LinkedHashMap。這里可以使用這個(gè)集合作為分組后用來(lái)保存返回值的容器。這樣就解決了分組后的排序問(wèn)題。
總結(jié)
以上是生活随笔為你收集整理的lamda list 分组_java8lambda表达式对集合分组并且排序(记一次性能优化案例)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 数据包格式_理解MQTT协议数据包结构
- 下一篇: 一只快乐的野指针_野酸枣