java自定义排序

2023-11-07


一、Arrays.sort(nums)的一般用法

  1. 整个数组按照升序排序
    若需要降序排序,将数组转置即可
int[] testNums = {1,3,6,5,4,1,2,8};
Arrays.sort(testNums);
System.out.println(Arrays.toString(testNums));

//输出:[1, 1, 2, 3, 4, 5, 6, 8]
  1. 对指定范围内的数组元素进行排序
int[] testNums2 = {1,3,6,5,4,1,2,8};
Arrays.sort(testNums2,1,6);
System.out.println(Arrays.toString(testNums2));

//输出:[1, 1, 3, 4, 5, 6, 2, 8]
  1. 自定义排序
    二维数组排序为例,比如,将:[[1,2],[3,4],[1,3],[2,4]] 按照每个一维数组的和的升序进行排序
int[][] testNums3 = {{1,2},{3,4},{1,3},{2,4}};
Arrays.sort(testNums3, new Comparator<int[]>() {
    @Override
    public int compare(int[] o1, int[] o2) {
        return (o1[0]+o1[1])-(o2[0]+o2[1]);
    }
});
for (int[] nums:testNums3){
    System.out.println(Arrays.toString(nums));
}

/*
    输出:
        [1, 2]
        [1, 3]
        [2, 4]
        [3, 4]
 */
  • 若要实现自定义排序,要给sort()函数传入一个继承Comparator接口的对象,在compare方法中定义自己的排序规则。
  • compare函数返回一个int类型:
    • o1,o2可以看成原数组中相邻的前后两个元素。返回值可以看成o1-o2的值。
    • 若返回负数,则说明o1-o2<0,sort方法将数组按升序(o1,o2)排列。
    • 反之若返回正数,说明o1-o2>0,按降序(o2,o1)排列。
    • 注意这里o1和o2并不一定能直接相加减,以上只是提供初学者一种记忆的方法,还是需要在实战中理解,接下来以两道算法题具体说明sort函数的一些应用。

4.使用lambda表达式自定义排序规则(重要!)

在3中,对应的接口函数可以用lambda表达式简写如下:

Arrays.sort(testNums3,(o1, o2) -> {
        return (o1[0]+o1[1])-(o2[0]+o2[1]);
    }
});

注意,要想改变默认的排列顺序,不能使用基本类型(int,double, char) ,而要使用它们对应的包装类。

二、最大数(力扣179)

原题连接
在这里插入图片描述

分析:先考虑两个数的情况,假设有两个数num1,num2,则答案要么是num1+num2,要么是num2+num1(注意这里的+表示拼接操作:1+2 = 12
定义num1>num2:num1+num2>num2+num1,举例说明:因为"3"+“31”=“331”>“31”+“3”=“313”,所以"3">“31”。
不难看出,当整个数组都按照我们定义的大小关系降序排序,最后依次拼接即为结果。比如:“31”>“30”>“2”,"31302"为所求最大数。代码如下:

public class Solution179 {
    /*
        给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。
        注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。

        输入:nums = [3,30,34,5,9]
        输出:"9534330"
        链接:https://leetcode-cn.com/problems/largest-number/
     */
    public static void main(String[] args) {
        int[] nums = {0,20,2190,5,38,21,1};
        System.out.println(Solution.largestNumber(nums));
    }
    static class Solution {
	    public static String largestNumber(int[] nums) {
	        String ans = "";
	        String[] temp = new String[nums.length];
	        for (int i = 0; i < nums.length; i++) {
	            temp[i] = Integer.toString(nums[i]);
	        }
	
	        Arrays.sort(temp, new Comparator<String>() {
	            @Override
	            public int compare(String o1, String o2) {
	                String o12 = o1+o2,o21 = o2+o1;
	                for (int i = 0; i < o12.length(); i++) {//逐个比较对应字符的大小
	                    //返回负数,顺序为(o1,o2)
	                    if(o12.charAt(i)>o21.charAt(i)) return -1;
	                    //返回正数,顺序为(o2,o1)
	                    else if(o12.charAt(i)<o21.charAt(i)) return 1;
	                    //无论是那种顺序,字符大的都在前面,因此是按降序排列
	                }
	                //若直到最后一个字符都相等,按照最后一个字符的大小来决定
	                return o12.charAt(o12.length()-1)<o21.charAt(o21.length()-1)?1:-1;
	            }
	        });
	        for (String s :
	                temp) {
	            ans += s;
	        }
	        return ans;
	    }
	}
}

三、合并区间(力扣59)

原题连接
在这里插入图片描述

分析:首先对intervals进行排序,排序规则为第一列按升序,第一列相等时第二列按降序,例如:[1,2]>[0,3],[2,2]>[2,3](思考为什么要这样排序)。
然后再遍历intervals进行合并。

  • 合并的过程中维护两个数值,左端点L,右端点R。
  • 一开始先给L和R赋初值为第一个区间的端点值,遍历intervals。
  • 若左端点和L相同,直接跳过(和一开始的排序有关)。
  • 若左端点大于L且大于R,说明L,R之间没有重叠区域了,记录L,R,并更新为当前区间的左右端点。
  • 若左端点大于L但是小于等于R,可能有重叠区域,将R更新为R与右端点之间的最大值。
  • 遍历结束后判断L,R是否记录。代码如下:
/*
    以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
    请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。

    [[1,3],[1,2],[2,6],[8,10],[15,18]]

    输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
    输出:[[1,6],[8,10],[15,18]]
    解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].

    链接:https://leetcode-cn.com/problems/merge-intervals
 */
public class Solution56 {
    public static void main(String[] args) {
        int[][] intervals =  {{1,3},{1,2},{2,6},{8,10},{15,18},{19,20}};
//        int[][] intervals =  {{1,4},{0,4}};
        System.out.println(Arrays.deepToString(Solution.merge(intervals)));

    }

    private static class Solution {
        public static int[][] merge(int[][] intervals) {
            //1.第一维升序,第二维降序进行排序
            //2.遍历数组,记录当前区间的端点;
            // 若下一个区间的左端点相同,直接跳过;若大于前一个的右端点,记录前一个区间,更新区间的左右端点;若小于前一个的右端点,则存在重合区域,更新区间端点
            int[][] ans = new int[10005][2];
            Arrays.sort(intervals, new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    if(o1[0]!=o2[0]) return o1[0]-o2[0];
                    else return o2[1]-o1[1];
                }
            });

            int L = 0,R = 0;//左右端点
            int nums = 0;//合并后的区间个数
            for (int i = 0; i < intervals.length; i++) {
                if(i==0){
                    L = intervals[0][0];R = intervals[0][1];continue;
                }
                if(intervals[i][0]==L) continue;//左区间端点相等直接跳过
                else if (intervals[i][0]>L){ //左区间端点大于前一个的左区间端点
                    if(intervals[i][0]>R){  //仍然大于右区间端点,记录
                        ans[nums][0] = L;ans[nums][1] = R;L = intervals[i][0];R = intervals[i][1];nums++;
                    }
                    else {//若小于等于右区间端点,比较它的右端点和原右端点的值,更新R
                        R = Math.max(intervals[i][1],R);
                    }
                }


            }

            //存在结束循环但是最后一个区间还没有加入ans的情况
            //最后一个区间也是首个区间
            if(nums==0) {ans[nums][0]=L;ans[nums][1]=R;}
            //最后一个区间不是首个区间的话只需要判断左端点是否相等,不相等说明还没有记录
            if(nums!=0 && ans[nums][0]!=L) {ans[nums][0]=L;ans[nums][1]=R;}

            return Arrays.copyOfRange(ans,0,nums+1);
        }
    }
}

四、总结

在理解各类排序算法的情况下,熟练使用Arrays.sort()方法解决问题,尤其掌握Comparator接口或lambda表达式的写法!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java自定义排序 的相关文章

  • 春天。使用java配置解决循环依赖而不使用@Autowired

    我有循环依赖和java配置 虽然使用 xml 配置解决它非常简单 但如果没有 Autowired 我无法使用 java 配置解决它 豆子 public class A private B b public B getB return b p
  • 在 Java 中将系统属性设置为 Null

    在我的单元测试中 我需要将 workingDir 系统属性设置为 Null 但我不能这样做 因为它给了我 NullPointerException System setProperty workingDir null 我该怎么做 您不能将属
  • Maven 配置文件相当于 Gradle

    我试图在我的 spring boot 项目构建中实现一个简单的场景 包括 排除依赖项以及根据环境打包 war 或 jar 例如 对于环境dev包括开发工具和包 jar 用于prod包战等 我知道它不再是基于 XML 的配置 我基本上可以在
  • 如何在 Spring Boot 1.4 中自定义 Jackson

    我一直无法找到如何使用的示例Jackson2ObjectMapperBuilderCustomizer java在spring boot 1 4中自定义Jackson的功能 boot 1 4 中自定义 Jackson 的 doco http
  • 使 TreeMap 比较器容忍 null

    这个定制的 Valuecomarator 按其值对 TreeMap 进行排序 但在搜索 TreeMap 是否具有某个键时 它不能容忍 nullpointException 如何修改比较器来处理零点 import java io IOExce
  • 使用 Java NIO 直接访问 Windows 磁盘

    我正在使用一个使用 Java NIO 的库来直接将文件映射到内存 但我在直接读取磁盘时遇到问题 I can直接使用读取磁盘FileInputStream与 UNC 合作 例如 File disk new File PhysicalDrive
  • 将图像缩略图上传到服务器,而不上传整个图像

    据我所知 我在这里问的是不可能的 但我想无论如何我都会问 以防我遗漏了什么 假设您想让用户上传 JPG 图像 并且这些图像被缩放为较小的图标 并且原始图像始终被丢弃并且不再需要 有没有什么方法可以在大多数现代浏览器中普遍使用 让用户选择硬盘
  • Selenium Webdriver 中显式等待 findElements

    登录后 页面重定向到一个页面 我想等待页面加载 我在其中按 tagName 查找元素 By inputArea By tagName input List
  • 找不到模块:javafx.controls

    我已经下载了JavaFX SDK 解压它并设置PATH TO FX系统变量 如下本说明 https openjfx io openjfx docs install javafx 我使用了以下代码示例 import javafx applic
  • 用dagger 2查看依赖注入

    我有一个自定义视图扩展TextView 我应该在哪里调用我的组件来注入视图 component inject customTextView 因此 我发现我需要在自定义视图的构造函数中添加注入 在所有视图中 或者使一个调用另一个 Exampl
  • 在java中将jpeg/png转换为像素数组

    如何将包含 jpeg 或 png 的字符串转换为像素数组 最好是一维 理想情况下使用java内置的类 原来你需要公共文件上传 http commons apache org fileupload 看着那 这用户指南 http commons
  • 在 jFrame 中启用右键单击

    嘿 我正在寻找如何使用 NetBeans 在 jFrame 中启用 仅且仅 右键单击并显示弹出菜单 使用我的代码 private void formMouseClicked java awt event MouseEvent evt pop
  • 如何告诉 Java SAX 解析器忽略无效字符引用?

    当尝试使用字符引用解析不正确的 XML 时 例如 x1 Java 的 SAX 解析器因致命错误而惨死 例如 org xml sax SAXParseException Character reference x1 is an invalid
  • 如何在 apache poi 中找到包含图片的单元格

    我尝试在 xls 文档中循环图像 我写下一个代码 HSSFPatriarch patriarch sheet getDrawingPatriarch if patriarch null Loop through the objects fo
  • 为什么 Libgdx 的 Table 不接受缩放操作?

    我在 libgdx 库中使用 scene2d 在游戏中创建一些 UI 我使用了一个表格 我想在用户触摸时采取一些缩放操作以使按钮触摸有意义 当我使用任何其他 Actor 类型 例如 Group 并为其提供缩放操作时 它可以工作 但不能工作表
  • Spring @Configuration如何缓存对bean的引用

    使用基于 Java 的配置时 Spring 如何防止再次调用 bar 我想知道编译时注释处理或通过代理方法 Configuration public class AppConfig Bean public Foo foo return ne
  • 在 Java Jersey 2 JAX-RS 中初始化单例

    我是泽西岛 2 22 2 的新手 请耐心等待 我正在创建一个与 LDAP 服务器交互的 REST 服务 用于存储 删除和检索用户数据 该服务通过执行加密 解密充当安全中介 在使用 REST 服务之前必须进行相当多的初始化 并且我只想执行此初
  • 如何避免连续“重置偏移量”和“寻找最新偏移量”?

    我正在尝试遵循本指南 https spark apache org docs latest structed streaming kafka integration html https spark apache org docs late
  • bean 中的 Spring JavaConfig 属性未设置?

    我正在考虑将 Spring JavaConfig 与一些属性文件一起使用 但 bean 中的属性未设置 bean 中的属性未设置 这是我的网络配置 Configuration EnableWebMvc PropertySource valu
  • 如果可能,将 jFrame 输出到第二台显示器

    我在 Java 中的 Swing 上有一个 jFrame 我希望它输出到第二个监视器 如果该监视器存在 我尝试过这个 通过this http download oracle com javase 6 docs api java awt Gr

随机推荐

  • 开源的杀毒软件

    开源的杀毒软件 有 免费的午餐 我们为什么不吃呢 杀毒软件一定要购买或用D版吗 先别忙着下结论 请耐心看完本文 然后再告诉我你是怎么想的 一 ClamWin Free Antivirus 开源反病毒软件 GPL协议 SourceForge页
  • Vmware 分辨率设置

    1 点击查看 2 点击自动调整大小 3 选择自动适应客户机即可
  • 简单怕忘笔记

    1 and REGEXP LIKE 字段名 匹配串1 匹配串2 全模糊匹配 2 and REGEXP LIKE 字段名 匹配串1 匹配串2 右模糊匹配 3 and REGEXP LIKE 字段名 匹配串1 匹配串2 左模糊匹配 4 LTRI
  • GNSS精密单点定位(PPP)基本原理(进阶篇)

    上节介绍了精密单点定位的基本原理 本文继续在精密单点定位的基础上进行更深层次的介绍 一 精密单点定位的函数模型 上节说过 在精密单点定位之前 也有一种绝对定位技术 那就是伪距单点定位 伪距单点定位靠的伪距进行单点定位 但是伪距的精度较差 主
  • 字符串转int数据类型的三种方式

    方法一 Integer valueOf 它将返回一个包装器类型 Integer 当然可以通过自动拆箱的方式将其转成 int 类型 String a 100 String b 50 int A Integer valueOf a int B
  • 睿智的智能优化算法3——利用遗传算法实现字符串配对

    睿智的智能优化算法3 利用遗传算法实现字符串配对 字符串配对 求解过程 1 编码方式 2 计算适应度 3 自然选择 4 基因突变 5 个体杂交 实现代码 GITHUB下载连接 好久都没有用过遗传算法了 觉得需要重新复习一下 而且考虑到遗传算
  • hive窗口函数(开窗函数)

    一 窗口函数概述 窗口函数 Window functions 是一种SQL函数 非常适合于数据分析 因此也叫做OLAP函数 其最大特点是 输入值是从SELECT语句的结果集中的一行或多行的 窗口 中获取的 你也可以理解为窗口有大有小 行有多
  • Tomcat服务器配置Https协议

    前言 日常开发项目时 一般本机都是基于http协议 但是要实现某些需求必须要开启https协议 现在https协议已经成为主流 网站如果未开启https协议 浏览器会进行安全提示 本文以Tomcat服务器为例 简单介绍如何在本机开发环境配置
  • ② 尚品汇的前台开发笔记【尚硅谷】【Vue】

    文章目录 八 加入购物车 路由跳转之前发请求 api 请求接口 将数据存储到服务器里 判断加入成功 或 失败 成功后进行路由跳转 开始进行路由跳转 并进行路由传参 开始渲染页面 购物车静态组件与修改 九 完成ShopCart购物车模块业务
  • 使用algorithm中的sort进行vector的自定义排序

    名称 使用algorithm中的sort进行vector的自定义排序 说明 可以使用sort进行自定义排序 不过要定义比较函数 在此处的比较 函数为Compare 名字可以任取 在比较函数中 定义自己的排序方式 然后在sort函数中传入函数
  • idea将本地新项目上传至svn

    目录 第一步 将本地代码交给svn管理 第二步 将代码提交至svn 第一步 将本地代码交给svn管理 1 file gt setting进入设置 2 点击Version Control gt 点击 加号 gt 选择本地项目文件 gt 选择S
  • 修改Mysql数据库的用户名和密码【详细】

    数据库的用户名默认是root 1进入到Mysql 首先要登录数据库 1win r输入cmd 管理员身份打开 或者 2搜索输入命令提示符 2 输入mysql uroot p点击回车 注意 mysql默认用户名是root 我以前修改过 所以我输
  • 看起来很长但还是有用的Spring学习笔记

    本文首发于泊浮目的专栏 https segmentfault com blog Spring致力于提供一种方法管理你的业务对象 在大量Java EE的应用中 随处可见Spring 今天我将简单的介绍一下Spring这个框架 本文适合读者 想
  • Verilog中generate语句的用法

    在Verilog 2001中新增了语句generate 通过generate循环 可以产生一个对象 比如一个元件或者是一个模块 的多次例化 为可变尺度的设计提供了方便 generate语句一般在循环和条件语句中使用 为此 Verilog 2
  • DLL的引入方式(DllImport的特殊引入方式)

    Dll引入方式有四种 1 就是普通的比如一个解决方案中有多个项目 将其他项目的引入到该项目中 2 就是软件自带的程序集的引入 3 就是使用dll的引入 普通的本身就是VS的dll文件 4 就是使用dll的引入 不是属于该语言的vs的Dll文
  • 减少GC开销 &&可能出现内存泄漏的情况&&两个对象相互引用会不会被GC

    如何降低java GC开销 减少GC次数 其他详见 如何减少垃圾回收的次数 jvm虚拟机 1 选择一个较好的GC器 Java9在2017年九月发布 G1 Garbage First 垃圾回收器 成为 HotSpot 虚拟机默认的垃圾回收器
  • 还没用熟 TypeScript 社区已经开始抛弃了

    前端Q 我是winty 专注分享前端知识和各类前端资源 乐于分享各种有趣的事 关注我 一起做个有趣的人 公众号 点击上方 前端Q 关注公众号 回复加群 加入前端Q技术交流群 根据 rich harris talks sveltekit an
  • C# 加密解码各种方法

    目录 一 加密解密介绍 二 MD5 三 SHA x系列 四 DES 3DES 五 RC2 六 AES 七 Base64 八 Rsa 九 参考文献 一 加密解密介绍 不可逆加密 MD5 SHA x系列对称式加密 Des 3DES RC2 AE
  • “加密系统”的巨坑

    在来公司之前 我压根就不知道这世界上原来还有 加密系统 这种软件产品存在 学名叫数据防泄漏 也怪我孤陋寡闻了 因为之前在厦门从来没听说过哪家公司有在用加密系统 当然 每家公司都有自己独特的管理需求 也许公司这边也确实重要信息比较多 核心机密
  • java自定义排序

    java中sort的自定义排序 一 Arrays sort nums 的一般用法 二 最大数 力扣179 三 合并区间 力扣59 四 总结 一 Arrays sort nums 的一般用法 整个数组按照升序排序 若需要降序排序 将数组转置即