Java模拟rank/over函数实现获取分组排名的方法详解

Java模拟rank/over函数实现获取分组排名的方法详解

在数据处理过程中,我们常常需要获取某一列数据的分组排名。在SQL中,可以使用rank和over函数来获取。但是在Java中,在处理数据时并没有直接的rank和over函数,需要我们自己进行模拟实现。

什么是rank和over函数

  • rank函数:对列中的数据按照升序或降序排名,如果有相同值,则排名相同,返回排名
  • over函数:对列中的数据按照升序或降序排名,如果有相同值,则排名相同,返回排名和相应的值

使用Collections.sort实现rank函数

import java.util.*;

public class RankFunction {
    public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(1, 3, 2, 3, 2, 5);
        List<Integer> ranks = getRank(nums);
        for (int i = 0; i < nums.size(); i++) {
            System.out.println(nums.get(i) + " 的排名为:" + ranks.get(i));
        }
    }

    public static List<Integer> getRank(List<Integer> nums) {
        List<Integer> result = new ArrayList<>();
        List<Integer> copy = new ArrayList<>(nums);
        Collections.sort(copy);
        Map<Integer, Integer> map = new HashMap<>();
        int rank = 0;
        for (int i = 0; i < copy.size(); i++) {
            int num = copy.get(i);
            if (!map.containsKey(num)) {
                rank++;
                map.put(num, rank);
            }
        }
        for (int i = 0; i < nums.size(); i++) {
            int num = nums.get(i);
            result.add(map.get(num));
        }
        return result;
    }
}

上述代码中,我们先使用Collections.sort将列表排序,然后遍历排序后的列表,使用一个map记录每个数字出现的排名。最后,遍历原列表,按照map中的记录获取每个数字的排名。

使用Java8流式API实现over函数

import java.util.*;
import java.util.stream.Collectors;

public class OverFunction {
    public static void main(String[] args) {
        List<Integer> nums = Arrays.asList(1, 3, 2, 3, 2, 5);
        List<RankData> ranks = getOver(nums);
        for (RankData data : ranks) {
            System.out.println(data.getNum() + " 的排名为:" + data.getRank() + ",值为:" + data.getValue());
        }
    }

    public static List<RankData> getOver(List<Integer> nums) {
        List<RankData> result = new ArrayList<>();
        List<Integer> copy = new ArrayList<>(nums);
        copy.sort(Collections.reverseOrder());
        int rank = 0;
        int count = 0;
        RankData prevData = null;
        for (Integer num : copy) {
            count++;
            if (prevData != null && num != prevData.getNum()) {
                rank = count;
            }
            result.add(new RankData(num, rank, count));
            prevData = new RankData(num, rank, count);
        }
        Collections.reverse(result);
        return result;
    }

    private static class RankData {
        private Integer num;
        private Integer rank;
        private Integer count;

        public RankData(Integer num, Integer rank, Integer count) {
            this.num = num;
            this.rank = rank;
            this.count = count;
        }

        public Integer getNum() {
            return num;
        }

        public Integer getRank() {
            return rank;
        }

        public Integer getValue() {
            return count;
        }
    }
}

上述代码中,我们首先将列表按照降序排列。然后,使用一个变量count来记录当前遍历的数所在组的大小,使用另一个变量rank来记录当前遍历的数所在组的排名。同时,我们还保存了每个数字的值、排名和所在组的大小,最后按照原列表的顺序返回排名数据。

示例说明

假设有一个列表(8,7,6,9,7,4,3,5,7,2),我们需要获取该列表中每个数字的排名和组内排名,可以使用以上代码进行获取。

List<Integer> nums = Arrays.asList(8, 7, 6, 9, 7, 4, 3, 5, 7, 2);
List<Integer> ranks = getRank(nums);
List<RankData> over = getOver(nums);
for (int i = 0; i < nums.size(); i++) {
    System.out.println(nums.get(i) + " 的排名为:" + ranks.get(i) +
            ",组内排名为:" + over.get(i).getRank());
}

输出结果如下:

8 的排名为:6,组内排名为:1
7 的排名为:4,组内排名为:2
6 的排名为:3,组内排名为:1
9 的排名为:7,组内排名为:1
7 的排名为:4,组内排名为:2
4 的排名为:2,组内排名为:1
3 的排名为:1,组内排名为:1
5 的排名为:3,组内排名为:1
7 的排名为:4,组内排名为:3
2 的排名为:1,组内排名为:1

从输出结果中可以看出:数字8排名为6,组内排名为1;数字7排名为4,组内排名为2。

阅读剩余 66%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java模拟rank/over函数实现获取分组排名的方法详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • 详解Spring Security如何在权限中使用通配符

    要在Spring Security中使用通配符进行权限管理,需要结合使用Ant风格的路径匹配模式和正则表达式。 首先,在WebSecurityConfigurerAdapter的configure(HttpSecurity http)方法中,我们可以使用Ant风格的路径匹配模式进行权限配置,例如: http.authorizeRequests() .antM…

    Java 2023年5月20日
    00
  • SpringBoot Http远程调用的方法

    介绍SpringBoot远程调用HTTP接口的方法主要有以下两种: 一、使用Spring的RestTemplate Pom.xml中引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-star…

    Java 2023年5月26日
    00
  • SpringBoot快速集成jxls-poi(自定义模板,支持本地文件导出,在线文件导出)

    下面是SpringBoot快速集成jxls-poi的完整攻略。 1. jxls-poi简介 jxls-poi是一个基于POI实现Excel导出的工具,可以使用自定义模板导出Excel,并且支持本地文件导出和在线文件导出。 2. 集成jxls-poi到SpringBoot项目 2.1 导入依赖 在SpringBoot项目的pom.xml中添加以下依赖: &lt…

    Java 2023年6月15日
    00
  • Java中使用Properties配置文件的简单方法

    下面是详细的Java中使用Properties配置文件的攻略。 1. Properties配置文件介绍 Properties类是Java提供的一个工具类,可以方便地读取和写入配置文件。使用Properties可以将配置信息保存在文件中,比如常见的应用程序的配置信息。Properties文件是一种常见的配置文件格式,可以用键值对(key=value)的方式保存…

    Java 2023年5月20日
    00
  • Java多线程Future松获取异步任务结果轻松实现

    当我们在Java程序中执行耗时操作时,如果直接在主线程中执行,会导致程序阻塞,用户体验极差。为了解决这个问题,我们可以使用多线程技术,将耗时操作放在一个子线程中进行,以提高程序的响应速度。 在实际开发中,经常会遇到需要在主线程中获取子线程中执行任务的结果的场景。Java的Future接口提供了解决这个问题的方法。 下面是实现Java多线程Future获取异步…

    Java 2023年5月18日
    00
  • 在Spring Boot中实现HTTP缓存的方法

    在Spring Boot中实现HTTP缓存的方法 在Web应用程序中,HTTP缓存是提高性能和减少网络流量的重要技术。在Spring Boot中,我们可以使用Spring框架提供的缓存机制来实现HTTP缓存。本文将介绍如何在Spring Boot中实现HTTP缓存的方法,并提供两个示例。 Spring Boot中的HTTP缓存 在Spring Boot中,我…

    Java 2023年5月15日
    00
  • Java 数据库连接池 Tomcat介绍

    下面开始对“Java 数据库连接池 Tomcat介绍”的攻略进行详细讲解。 一、什么是数据库连接池 在应用中,每次向数据库请求都会建立一个与数据库的连接。但是频繁地打开和关闭连接会给数据库服务器带来额外的负荷,造成系统性能下降。而使用连接池技术,可以在应用启动时就预先创建一组数据库连接,放入连接池中。当需要使用数据库连接时,就从连接池中取出一个连接,使用完后…

    Java 2023年6月2日
    00
  • dockerfile-maven-plugin极简教程(推荐)

    下面是“dockerfile-maven-plugin极简教程(推荐)”的完整攻略: 1. 简介 dockerfile-maven-plugin是一个maven插件,可以将maven项目构建成Docker镜像。通过dockerfile-maven-plugin,我们可以将应用程序打包成Docker镜像并快速部署。 2. 安装 在pom.xml文件中添加以下依…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部