SpringBoot进阶教程(七十六)多维度排序查询

这篇具有很好参考价值的文章主要介绍了SpringBoot进阶教程(七十六)多维度排序查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

v需求背景

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

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

v代码实现

创建user类
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());
    }
}
debug效果

SpringBoot进阶教程(七十六)多维度排序查询

v源码地址

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


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

到了这里,关于SpringBoot进阶教程(七十六)多维度排序查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 桥接模式-处理多维度变化

     程序员小名去摆摊卖奶茶了,口味有香、甜。 型号有大、中、小。假如小名先在家里把这些奶茶装好,那么最少要装2x3 = 6杯奶茶,如果此时新增一个口味:酸,那么就需要多装3杯奶茶了。而且这样做,等客户买走一种,比如 甜+大杯后,这种型号就没有了,这样扩展性不太

    2024年02月16日
    浏览(37)
  • 模板特化的多维度挖掘

       假如我有一个需求,就是如果传入的参数是int类型,我就输出int类型,否则就输出T。很显然,根据模板的基础知识,我们可以这么写    除了这样写,还有别的写法吗。我们可以思考一下.................这里我们其实可以用std::enable_if_t来实现,它相当于给std::enable_if的

    2024年02月08日
    浏览(35)
  • 3.1 多维度随机变量及其分布

          要学习二维随机变量及联合分布,我会按照以下步骤进行: 了解基本概念:首先要了解二维随机变量的概念,即同时包含两个随机变量的变量。还要了解二维随机变量的取值范围以及联合概率密度函数和联合分布函数的定义。 学习联合分布函数的性质:联合分布函数

    2024年02月06日
    浏览(62)
  • AIGC ChatGPT 实现动态多维度分析雷达图制作

    雷达图在多维度分析中是一种非常实用的可视化工具,主要有以下优势: 易于理解: 雷达图使用多边形或者圆形的形式展示多维度的数据,直观易于理解。 多维度对比: 雷达图可以在同一张图上比较多个项目或者实体在多个维度上的表现。 数据关系明显: 通过雷达图,可

    2024年02月11日
    浏览(46)
  • 异构区块链的多维度安全检测方案

    摘 要 :异构区块链多维度安全检测方案可以为多样化的区块链平台安全性检测提供统一的测评标准和检测方法,辅助相关部门对区块链平台进行有效检测和监管,促进区块链行业的合规发展。通过分析现有区块链安全检测的需求,针对目前多样性的区块链底层平台,提出普

    2024年02月05日
    浏览(40)
  • Python多维矩阵的各个维度表示(axis = ......)

    在python中对多维矩阵进行操作时,往往要指定操作的维度,一般用0,1,-1这样的数字表示矩阵的某一维度。二维矩阵还是好分辨数字表示的维度的,但对于三维矩阵或更高维度的矩阵就不好分辨了。这里只说明三维矩阵的三个维度怎么分辨。 以一个三维矩阵按不同维度求和

    2024年02月13日
    浏览(35)
  • 多维度聊一聊 k8s 和 openstack

    k8s 和 openstack 无疑是当今云计算领域的两大巨头,它们分别占据着 IaaS 和 PaaS 领域的事实标准,经常被拿来一起比较。我记得大概在三四年前 k8s 如火如荼的发展的时候,“openstack 已死”,“openstack 没落了”之类的文章层出不穷。但是这么年过去了 openstack 老当益壮依然在云

    2024年01月22日
    浏览(45)
  • Matlab 线性拟合、一维、多维度非线性拟合、多项式拟合

      线性拟合 我随便设定一个函数然后通过解方程计算出对应的系数 假设我的函数原型是 y=a*sin(0.1*x.^2+x)+b* squre(x+1)+c*x+d  拟合系数:   利用matlab实现非线性拟合(三维、高维、参数方程)_matlab多元非线性拟合_hyhhyh21的博客-CSDN博客 简单的一维的拟合: 思路: 将非线性-》线

    2024年02月12日
    浏览(46)
  • 《扬帆优配》两融业务不乏亮点 仍需多维度补短板

    受多重因素影响,2022年证券职业全体成绩承压。不过,到3月29日晚记者发稿时,从已发表的7家上市券商2022年年报来看,券商在两融事务方面不乏亮点。   受访业内人士表明,两融事务的开展不仅丰厚了券商的收入,也促进了券商其他事务的开展。可是,两融事务开展中存在

    2024年02月02日
    浏览(41)
  • 抛开价格,DBeaver真的比Navicat好用吗?多维度测评来了!!!

    今天看到一个很有意思的话题“抛开价格,DBeaver真的比Navicat好用吗?” ,正好自己最近使用的数据库连接工具比较多,两个软件都有使用过,我以自己的使用体验给你对比一下,从这个方面去对比: 1、下载难易 DBeaver是个开源软件,比较容易利用现有的网络资源找到安装包。

    2024年02月16日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包