SpringBoot进阶教程(七十六)多维度排序查询
2023/6/11 1:22:18
本文主要是介绍SpringBoot进阶教程(七十六)多维度排序查询,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在项目中经常能遇到,需要对某些数据集合进行多维度排序的需求。对于集合多条件排序解决方案也有很多,今天我们就介绍一种,思路大致是设置一个分值的集合,这个分值是按照需求来设定大小的,再根据分值的大小对集合排序。
v需求背景
我们来模拟一个需求,现在需要查询一个用户列表,该列表需要实现的排序优先级如下:
- 付费用户排在前,非付费用户排在后
- 付费用户中,排序优先级:同城市的>同省的>等级高的>活跃用户>不活跃用户>其他用户
- 非付费用户中,排序优先级:等级高的>同城市的>其他用户
v代码实现
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; /** * 等级 */ private int grade; /** * 所在省份id */ private int provinceId; /** * 所在城市ID */ private int cityId; /** * 是否是活跃用户,true活跃,false不活跃 */ private boolean lively; /** * 是否开通支付,true开通,false未开通 */ 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; } }
为了便于调试,我们在user类中创建一个测试方法getTestUserList,以此来生成测试数据。
package com.util; import java.math.BigDecimal; import java.util.List; /** * @Author toutou * @Date 2023/2/18 * @Des */ public class SortHelper { /** * 比较两个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 { /** * 当前用户所在城市id,所在省份id * @param cityId * @param provinceId * @return */ public List<User> sortUserList(int cityId, int provinceId) { // 获取初始化测试list数据 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){ // 初始化一个排序的分值list List<BigDecimal> scoreList = Flux.range(0, 6).map(p -> BigDecimal.ZERO).collectList().block(); userAndScore.add(new ImmutablePair<>(user, scoreList)); if(user.isPay()){ // 付费用户排序,付费用户为1,非付费用户为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
这篇关于SpringBoot进阶教程(七十六)多维度排序查询的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27JavaScript面试真题详解与解答
- 2024-12-27掌握JavaScript大厂面试真题:新手入门指南
- 2024-12-27JavaScript 大厂面试真题详解与解析
- 2024-12-26网络攻防资料入门教程
- 2024-12-26SQL注入资料详解:入门必读教程
- 2024-12-26初学者指南:数据库服务漏洞项目实战
- 2024-12-26网络安全项目实战:新手入门指南
- 2024-12-26网络攻防项目实战入门教程
- 2024-12-26信息安全项目实战:从入门到初步应用
- 2024-12-26SQL注入项目实战:初学者指南