经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
SpringBoot进阶教程(七十六)多维度排序查询
来源:cnblogs  作者:请叫我头头哥  时间:2023/6/12 10:29:26  对本文有异议

在项目中经常能遇到,需要对某些数据集合进行多维度排序的需求。对于集合多条件排序解决方案也有很多,今天我们就介绍一种,思路大致是设置一个分值的集合,这个分值是按照需求来设定大小的,再根据分值的大小对集合排序。

v需求背景

我们来模拟一个需求,现在需要查询一个用户列表,该列表需要实现的排序优先级如下:

  • 付费用户排在前,非付费用户排在后
  • 付费用户中,排序优先级:同城市的>同省的>等级高的>活跃用户>不活跃用户>其他用户
  • 非付费用户中,排序优先级:等级高的>同城市的>其他用户

v代码实现

创建user类
  1. package com.user;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Builder;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * @Author toutou
  10. * @Date 2023/2/18
  11. * @Des
  12. */
  13. @Data
  14. @AllArgsConstructor
  15. @NoArgsConstructor
  16. @Builder
  17. public class User {
  18. private Integer id;
  19. /**
  20. * 等级
  21. */
  22. private int grade;
  23. /**
  24. * 所在省份id
  25. */
  26. private int provinceId;
  27. /**
  28. * 所在城市ID
  29. */
  30. private int cityId;
  31. /**
  32. * 是否是活跃用户,true活跃,false不活跃
  33. */
  34. private boolean lively;
  35. /**
  36. * 是否开通支付,true开通,false未开通
  37. */
  38. private boolean pay;
  39. public static List<User> getTestUserList() {
  40. List<User> list = new ArrayList<>();
  41. list.add(User.builder().id(0).grade(1).provinceId(1).cityId(22).lively(false).pay(false).build());
  42. list.add(User.builder().id(1).grade(1).provinceId(1).cityId(100).lively(true).pay(true).build());
  43. list.add(User.builder().id(2).grade(3).provinceId(5).cityId(100).lively(true).pay(true).build());
  44. list.add(User.builder().id(3).grade(2).provinceId(1).cityId(98).lively(true).pay(true).build());
  45. list.add(User.builder().id(4).grade(2).provinceId(1).cityId(100).lively(true).pay(true).build());
  46. list.add(User.builder().id(5).grade(2).provinceId(3).cityId(100).lively(true).pay(true).build());
  47. list.add(User.builder().id(6).grade(2).provinceId(1).cityId(101).lively(true).pay(false).build());
  48. list.add(User.builder().id(7).grade(1).provinceId(6).cityId(100).lively(false).pay(true).build());
  49. list.add(User.builder().id(8).grade(1).provinceId(1).cityId(98).lively(true).pay(false).build());
  50. list.add(User.builder().id(9).grade(1).provinceId(5).cityId(100).lively(true).pay(true).build());
  51. return list;
  52. }
  53. }

为了便于调试,我们在user类中创建一个测试方法getTestUserList,以此来生成测试数据。

创建排序帮助类
  1. package com.util;
  2. import java.math.BigDecimal;
  3. import java.util.List;
  4. /**
  5. * @Author toutou
  6. * @Date 2023/2/18
  7. * @Des
  8. */
  9. public class SortHelper {
  10. /**
  11. * 比较两个BigDecimal集合
  12. * @param left
  13. * @param right
  14. * @return leftList<rightList返回-1;leftList=rightList返回0;leftList>rightList返回1;
  15. */
  16. public static int compareBigDecimalList(List<BigDecimal> left, List<BigDecimal> right) {
  17. int length = Math.max(left.size(), right.size());
  18. for (int i = 0; i < length; i++) {
  19. if (left.size() < i + 1) {
  20. return -1;
  21. }
  22. if (right.size() < i + 1) {
  23. return 1;
  24. }
  25. int value = left.get(i).compareTo(right.get(i));
  26. if (value != 0) {
  27. return value;
  28. }
  29. }
  30. return 0;
  31. }
  32. }
排序实现类
  1. package com.util;
  2. import com.user.User;
  3. import org.apache.commons.lang3.tuple.ImmutablePair;
  4. import java.math.BigDecimal;
  5. import java.util.ArrayList;
  6. import java.util.Comparator;
  7. import java.util.List;
  8. import java.util.stream.Collectors;
  9. import reactor.core.publisher.Flux;
  10. /**
  11. * @Author toutou
  12. * @Date 2023/2/18
  13. * @Des
  14. */
  15. public class Sort {
  16. /**
  17. * 当前用户所在城市id,所在省份id
  18. * @param cityId
  19. * @param provinceId
  20. * @return
  21. */
  22. public List<User> sortUserList(int cityId, int provinceId) {
  23. // 获取初始化测试list数据
  24. List<User> list = User.getTestUserList();
  25. if(list == null || list.size() == 0){
  26. return list;
  27. }
  28. List<ImmutablePair<User, List<BigDecimal>>> userAndScore = new ArrayList<>();
  29. for (User user : list){
  30. // 初始化一个排序的分值list
  31. List<BigDecimal> scoreList = Flux.range(0, 6).map(p -> BigDecimal.ZERO).collectList().block();
  32. userAndScore.add(new ImmutablePair<>(user, scoreList));
  33. if(user.isPay()){
  34. // 付费用户排序,付费用户为1,非付费用户为2
  35. scoreList.set(0, BigDecimal.valueOf(1));
  36. if(user.getCityId() == cityId){
  37. scoreList.set(1, BigDecimal.valueOf(1));
  38. }else{
  39. scoreList.set(1, BigDecimal.valueOf(2));
  40. }
  41. if(user.getProvinceId() == provinceId){
  42. scoreList.set(2, BigDecimal.valueOf(1));
  43. }else{
  44. scoreList.set(2, BigDecimal.valueOf(2));
  45. }
  46. scoreList.set(3, BigDecimal.valueOf(-user.getGrade()));
  47. if(user.isLively()){
  48. scoreList.set(4, BigDecimal.valueOf(1));
  49. }else{
  50. scoreList.set(4, BigDecimal.valueOf(2));
  51. }
  52. scoreList.set(5, BigDecimal.valueOf(-user.getId()));
  53. }else{
  54. scoreList.set(0, BigDecimal.valueOf(2));
  55. scoreList.set(1, BigDecimal.valueOf(-user.getGrade()));
  56. if(user.getCityId() == cityId){
  57. scoreList.set(2, BigDecimal.valueOf(1));
  58. }else{
  59. scoreList.set(2, BigDecimal.valueOf(2));
  60. }
  61. scoreList.set(3, BigDecimal.valueOf(-user.getId()));
  62. }
  63. }
  64. return userAndScore.stream().sorted(Comparator.comparing(p -> p.getValue(), SortHelper::compareBigDecimalList)).map(ImmutablePair::getLeft).collect(Collectors.toList());
  65. }
  66. }
debug效果

请叫我头头哥

v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn


作  者:请叫我头头哥
出  处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

原文链接:https://www.cnblogs.com/toutou/p/springboot_sort.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号