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

yizhihongxing

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。

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

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

相关文章

  • t01_idea消除的白框

    消除idea顶部窗口上的白色标题栏 点击Hlep,找到Edit Custom VM Options…点击 添加下面一段话(如果有责显示为false责改为true): -Dide.win.frame.decoration=true 然后重启即可,如下图所示,顶部白框已经没有出现了 原文链接:https://www.cnblogs.com/2580p/p/1…

    Java 2023年5月2日
    00
  • 详解HTTP请求与响应基础及实例

    详解HTTP请求与响应基础及实例 HTTP是一种用于网络传输的协议,它定义了客户端和服务器之间进行通信的规则。在HTTP通信过程中,客户端向服务器发送请求,服务器则对请求进行处理并返回响应,由此构成了HTTP请求和响应的基础。 HTTP请求 HTTP请求由三部分构成:请求行、请求头和请求体。其中,请求行包含请求的方法、URI和HTTP版本号,请求头包含了请求…

    Java 2023年5月20日
    00
  • JVM中对象的创建与OOP-Klass模型

    一、JVM中对象的创建 在Java中,对象的创建过程必须经过如下步骤: JVM读入指定类的二进制数据,并在方法区中生成类模板,同时为类变量和静态变量分配内存空间; JVM在堆上分配实际的对象空间,同时根据不同的访问控制权限设置对象的内部成员; 在对象空间中执行实例方法时,虚拟机通过对象的指针调用相应方法。 二、OOP-Klass模型 OOP-Klass模型是…

    Java 2023年5月26日
    00
  • request如何获取body的json数据

    获取HTTP请求的request body是常见的开发任务。在Node.js中,可以使用body-parser中间件来解析请求体解析成JSON对象。以下是获取HTTP请求的request body的完整攻略。 步骤1:安装body-parser中间件 在Node.js应用程序中,安装和使用body-parser中间件是处理请求体最常见的方法。要安装它,请使用…

    Java 2023年5月26日
    00
  • Java Apache Commons报错“UnhandledException”的原因与解决方法

    “UnhandledException”是Java的ApacheCommons类库中的一个异常,通常由以下原因之一引起: 代码错误:如果代码中存在错误,则可能会出现此异常。例如,可能会使用错误的方法或参数。 系统错误:如果系统中存在错误,则可能会出现此异常。例如,可能会出现内存不足或文件系统错误。 以下是两个实例: 例1 如果代码中存在错误,则可以尝试检查代…

    Java 2023年5月5日
    00
  • tomcat logs 目录下各日志文件的解析(小结)

    tomcat logs 目录下各日志文件的解析(小结) Tomcat是一个流行的Web应用服务器,它会生成各种日志文件。在Tomcat logs 目录下,通常会有以下几类日志文件: catalina.out:Tomcat的控制台输出日志文件,包含了Tomcat启动时的各种信息。 localhost.<日期>.log:每个Web应用程序的日志文件,…

    Java 2023年6月2日
    00
  • Java实现的数组去重与排序操作详解

    Java实现的数组去重与排序操作详解 1. 去重操作 1.1 利用HashSet去重 利用HashSet可以对无序数组进行去重,操作属于较为简单的算法。 示例代码如下: public static int[] removeDuplicates(int[] nums) { Set<Integer> set = new HashSet<>…

    Java 2023年5月26日
    00
  • Java 判断一个时间是否在另一个时间段内

    下面我就来详细讲解一下 “Java 判断一个时间是否在另一个时间段内” 的完整攻略。 1. 获取时间和时间段 首先,我们需要获取到我们要比较的时间和时间段。在Java中,可以使用以下两种方式来获取时间和时间段: (1)Date类型 Java中Date类表示一个时间点,可以使用new Date()来获取当前时间。如果需要指定具体的时间可以使用new Date(…

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