在項(xiàng)目中經(jīng)常能遇到,需要對(duì)某些數(shù)據(jù)集合進(jìn)行多維度排序的需求。對(duì)于集合多條件排序解決方案也有很多,今天我們就介紹一種,思路大致是設(shè)置一個(gè)分值的集合,這個(gè)分值是按照需求來(lái)設(shè)定大小的,再根據(jù)分值的大小對(duì)集合排序。
v需求背景
我們來(lái)模擬一個(gè)需求,現(xiàn)在需要查詢一個(gè)用戶列表,該列表需要實(shí)現(xiàn)的排序優(yōu)先級(jí)如下:
- 付費(fèi)用戶排在前,非付費(fèi)用戶排在后
- 付費(fèi)用戶中,排序優(yōu)先級(jí):同城市的>同省的>等級(jí)高的>活躍用戶>不活躍用戶>其他用戶
- 非付費(fèi)用戶中,排序優(yōu)先級(jí):等級(jí)高的>同城市的>其他用戶
v代碼實(shí)現(xiàn)
package com.user; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; /** * @Author toutou * @Date 2023/2/18 * @Des */ @Data @AllArgsConstructor @NoArgsConstructor @Builder public class User { private Integer id; /** * 等級(jí) */ private int grade; /** * 所在省份id */ private int provinceId; /** * 所在城市ID */ private int cityId; /** * 是否是活躍用戶,true活躍,false不活躍 */ private boolean lively; /** * 是否開(kāi)通支付,true開(kāi)通,false未開(kāi)通 */ private boolean pay; public static List<User> getTestUserList() { List<User> list = new ArrayList<>(); list.add(User.builder().id(0).grade(1).provinceId(1).cityId(22).lively(false).pay(false).build()); list.add(User.builder().id(1).grade(1).provinceId(1).cityId(100).lively(true).pay(true).build()); list.add(User.builder().id(2).grade(3).provinceId(5).cityId(100).lively(true).pay(true).build()); list.add(User.builder().id(3).grade(2).provinceId(1).cityId(98).lively(true).pay(true).build()); list.add(User.builder().id(4).grade(2).provinceId(1).cityId(100).lively(true).pay(true).build()); list.add(User.builder().id(5).grade(2).provinceId(3).cityId(100).lively(true).pay(true).build()); list.add(User.builder().id(6).grade(2).provinceId(1).cityId(101).lively(true).pay(false).build()); list.add(User.builder().id(7).grade(1).provinceId(6).cityId(100).lively(false).pay(true).build()); list.add(User.builder().id(8).grade(1).provinceId(1).cityId(98).lively(true).pay(false).build()); list.add(User.builder().id(9).grade(1).provinceId(5).cityId(100).lively(true).pay(true).build()); return list; } }
為了便于調(diào)試,我們?cè)趗ser類中創(chuàng)建一個(gè)測(cè)試方法getTestUserList,以此來(lái)生成測(cè)試數(shù)據(jù)。
package com.util; import java.math.BigDecimal; import java.util.List; /** * @Author toutou * @Date 2023/2/18 * @Des */ public class SortHelper { /** * 比較兩個(gè)BigDecimal集合 * @param left * @param right * @return leftList<rightList返回-1;leftList=rightList返回0;leftList>rightList返回1; */ public static int compareBigDecimalList(List<BigDecimal> left, List<BigDecimal> right) { int length = Math.max(left.size(), right.size()); for (int i = 0; i < length; i++) { if (left.size() < i + 1) { return -1; } if (right.size() < i + 1) { return 1; } int value = left.get(i).compareTo(right.get(i)); if (value != 0) { return value; } } return 0; } }
package com.util; import com.user.User; import org.apache.commons.lang3.tuple.ImmutablePair; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import reactor.core.publisher.Flux; /** * @Author toutou * @Date 2023/2/18 * @Des */ public class Sort { /** * 當(dāng)前用戶所在城市id,所在省份id * @param cityId * @param provinceId * @return */ public List<User> sortUserList(int cityId, int provinceId) { // 獲取初始化測(cè)試list數(shù)據(jù) List<User> list = User.getTestUserList(); if(list == null || list.size() == 0){ return list; } List<ImmutablePair<User, List<BigDecimal>>> userAndScore = new ArrayList<>(); for (User user : list){ // 初始化一個(gè)排序的分值list List<BigDecimal> scoreList = Flux.range(0, 6).map(p -> BigDecimal.ZERO).collectList().block(); userAndScore.add(new ImmutablePair<>(user, scoreList)); if(user.isPay()){ // 付費(fèi)用戶排序,付費(fèi)用戶為1,非付費(fèi)用戶為2 scoreList.set(0, BigDecimal.valueOf(1)); if(user.getCityId() == cityId){ scoreList.set(1, BigDecimal.valueOf(1)); }else{ scoreList.set(1, BigDecimal.valueOf(2)); } if(user.getProvinceId() == provinceId){ scoreList.set(2, BigDecimal.valueOf(1)); }else{ scoreList.set(2, BigDecimal.valueOf(2)); } scoreList.set(3, BigDecimal.valueOf(-user.getGrade())); if(user.isLively()){ scoreList.set(4, BigDecimal.valueOf(1)); }else{ scoreList.set(4, BigDecimal.valueOf(2)); } scoreList.set(5, BigDecimal.valueOf(-user.getId())); }else{ scoreList.set(0, BigDecimal.valueOf(2)); scoreList.set(1, BigDecimal.valueOf(-user.getGrade())); if(user.getCityId() == cityId){ scoreList.set(2, BigDecimal.valueOf(1)); }else{ scoreList.set(2, BigDecimal.valueOf(2)); } scoreList.set(3, BigDecimal.valueOf(-user.getId())); } } return userAndScore.stream().sorted(Comparator.comparing(p -> p.getValue(), SortHelper::compareBigDecimalList)).map(ImmutablePair::getLeft).collect(Collectors.toList()); } }
v源碼地址
https://github.com/toutouge/javademosecond/tree/master/hellolearn文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-478259.html
作 者:請(qǐng)叫我頭頭哥
出 處:http://www.cnblogs.com/toutou/
關(guān)于作者:專注于基礎(chǔ)平臺(tái)的項(xiàng)目開(kāi)發(fā)。如有問(wèn)題或建議,請(qǐng)多多賜教!
版權(quán)聲明:本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接。
特此聲明:所有評(píng)論和私信都會(huì)在第一時(shí)間回復(fù)。也歡迎園子的大大們指正錯(cuò)誤,共同進(jìn)步?;蛘咧苯铀叫盼?
聲援博主:如果您覺(jué)得文章對(duì)您有幫助,可以點(diǎn)擊文章右下角【推薦】一下。您的鼓勵(lì)是作者堅(jiān)持原創(chuàng)和持續(xù)寫(xiě)作的最大動(dòng)力!
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-478259.html
到了這里,關(guān)于SpringBoot進(jìn)階教程(七十六)多維度排序查詢的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!