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。

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

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

相关文章

  • Java对象转json的方法过程解析

    下面我将为您详细讲解Java对象转json的方法过程解析的完整攻略。 什么是json JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,语法简单明了,易于阅读和编写,同时也易于机器解析和生成,可以用于前后端数据交互等场景。 Java对象转json的方法 Java中比较流行的json工具包有Gson和Jackson,这…

    Java 2023年5月26日
    00
  • java 读写 ini 配置文件的示例代码

    要读写ini配置文件,我们可以使用Java的Properties类。Properties类提供了一种简单的机制来将“key-value”对存储到配置文件中,并从中检索。 以下是读取配置文件的示例代码: import java.io.FileInputStream; import java.util.Properties; public class ReadI…

    Java 2023年5月19日
    00
  • IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案

    下面是详细讲解“IDEA中创建maven项目引入相关依赖无法下载jar问题及解决方案”的完整攻略。 问题描述 在使用IntelliJ IDEA创建Maven项目时,通过编辑POM.XML文件引入相关依赖,但是发现IDEA无法下载所需的JAR包,导致项目无法编译运行。 可能原因 上述依赖库不存在。 依赖库被墙了。 IDEA配置问题。 解决方案 方案一:更改本地…

    Java 2023年5月19日
    00
  • SpringBoot项目实战之加载和读取资源文件

    下面我将详细讲解“SpringBoot项目实战之加载和读取资源文件”的完整攻略。 加载资源文件 加载classpath中的资源文件 在SpringBoot项目中,我们可以使用ClassLoader来读取classpath中的资源文件,例如: InputStream inputStream = this.getClass().getClassLoader().…

    Java 2023年6月2日
    00
  • Java7之forkjoin简介_动力节点Java学院整理

    首先,我们需要了解什么是Fork/Join框架。简单来说,它是Java7中提供的一种用于实现并发编程的框架,通过将一个大任务拆分成多个子任务,然后将这些子任务分别交给不同的线程执行,最后将子任务的结果合并得到大任务的结果,从而提高程序的执行效率。 接下来,我们详细介绍一下如何使用Fork/Join框架来实现并发编程。首先需要创建一个继承自java.util.…

    Java 2023年5月26日
    00
  • Java8新特性:Lambda表达式之方法引用详解

    Java8新特性:Lambda表达式之方法引用详解 Java 8中引入了Lambda表达式,使得Java中的函数式编程变得更加简单。方法引用是Lambda表达式的一种特殊形式,让我们能够重复利用已有方法的实现。 方法引用的概念 方法引用是一个简写形式,它提供了一种方式,让我们可以使用已有方法的规则来编写Lambda表达式。简单来说,方法引用允许你直接引用现有…

    Java 2023年5月26日
    00
  • SpringBoot环境搭建图文教程

    下面就来详细讲解一下如何搭建Spring Boot环境。 1. 安装Java JDK 首先需要安装Java JDK,从Oracle官网下载JDK安装包,并按照提示进行安装。安装完成后,可以通过运行以下命令检查是否安装成功: java -version 2. 安装Maven Spring Boot项目通常使用Maven构建,所以需要先安装Maven。从官网下载…

    Java 2023年5月15日
    00
  • 详解在springboot中使用Mybatis Generator的两种方式

    下面我将详细讲解“详解在springboot中使用Mybatis Generator的两种方式”的完整攻略。 一、前置条件 在使用Mybatis Generator之前,我们需要先满足以下几个前置条件: 安装Maven和JDK,在此不再赘述; 在项目中引入依赖mybatis-generator-core和mysql-connector-java,可以在pom…

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