Java 排序

news2024/11/14 22:05:23

Java 排序

在这里插入图片描述

1 Collection 排序

Collections类中的:

  1. sort方法可以对List对象进行排序,该方法使用自然排序,即根据元素的自然顺序进行排序。
  2. 如果需要对自定义对象进行排序,需要实现Comparable接口并重写compareTo方法
  3. Collections类还提供了一些静态方法,如reverse和shuffle,可以对集合进行反转和随机排序
import java.util.Arrays;  
import java.util.List;  
import java.util.Collections;  
  
public class SortListExample {  
    public static void main(String[] args) {  
        List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5);  
          
        // 使用 sort 方法对 List 进行排序  
        numbers.sort(null); // 默认按照自然顺序排序  
        System.out.println("Sorted list: " + numbers); // 输出: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]  
          
        // 使用自定义的 Comparator 对 List 进行排序  
        numbers.sort(new Comparator<Integer>() {  
            @Override  
            public int compare(Integer o1, Integer o2) {  
                return o2 - o1; // 降序排序  
            }  
        });  
        System.out.println("Custom sorted list: " + numbers); // 输出: [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]  
    }  
}

2 Object[] 数据排序

import java.util.Arrays;  
import java.util.Comparator;  
  
public class SortExample {  
    public static void main(String[] args) {  
        String[] elementData = {"apple", "banana", "cherry", "date", "elderberry"};  
        int size = 3; // 只排序前三个元素  
          
        Arrays.sort(elementData, 0, size, new Comparator<String>() {  
            @Override  
            public int compare(String o1, String o2) {  
                return o1.length() - o2.length(); // 按字符串长度排序  
            }  
        });  
          
        System.out.println(Arrays.toString(elementData)); // 输出排序后的数组 [apple, cherry, banana]  
    }  
}

3 Map排序

Map 本身是一种无序的数据结构,因此排序操作通常需要在遍历或转换时进行

3.1 TreeMap:TreeMap 默认按键(key)的自然顺序进行排序,也可以通过构造器传入自定义的 Comparator 来实现自定义排序。TreeMap 在插入、删除和查找元素时,都会按照键的顺序进行排序。

    public static <K, V> Map<K, V> sortByKey(Map<K, V> unsortedMap) {
        Map<K, V> sortedMap = new TreeMap<>(unsortedMap);
        return sortedMap;
    }

3.1.1 使用自定义的Comparator:TreeMap 允许通过提供一个自定义的 Comparator 来对键(key)进行排序。如果希望在 TreeMap 中按键的自定义顺序存储元素,可以在创建 TreeMap 实例时传递一个自定义的 Comparator。

import java.util.Comparator;  
import java.util.TreeMap;  
  
public class TreeMapExample {  
    public static void main(String[] args) {  
        // 创建一个自定义的 Comparator,用于 TreeMap 中的键排序  
        Comparator<String> customComparator = new Comparator<String>() {  
            @Override  
            public int compare(String o1, String o2) {  
                // 按照字符串长度进行排序  
                return o1.length() - o2.length();  
            }  
        };  
  
        // 使用自定义的 Comparator 创建 TreeMap  
        TreeMap<String, Integer> treeMap = new TreeMap<>(customComparator);  
  
        // 向 TreeMap 中添加元素  
        treeMap.put("apple", 1);  
        treeMap.put("banana", 2);  
        treeMap.put("cherry", 3);  
        treeMap.put("date", 4);  
  
        // 遍历 TreeMap,输出排序后的键值对  
        for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {  
            System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());  
        }  
    }  
}

3.1.2 TreeMap 根据值进行排序
TreeMap 本身并不直接支持根据值(value)进行排序,因为它的设计初衷是按键(key)的自然顺序或提供的 Comparator 进行键排序。如果需要根据值对 TreeMap 进行排序,可以采取以下步骤:
a. 将 TreeMap 转换为一个 List,其中包含键值对(Map.Entry)。
b. 使用 Collections.sort() 方法对这个列表进行排序,并提供一个自定义的比较器(Comparator),该比较器根据值进行比较。
c. 遍历排序后的列表,并根据需要重新构造一个 TreeMap 或其他数据结构。

import java.util.*;  
  
public class TreeMapByValueExample {  
    public static void main(String[] args) {  
        // 创建一个 TreeMap  
        TreeMap<String, Integer> treeMap = new TreeMap<>();  
        treeMap.put("A", 10);  
        treeMap.put("B", 5);  
        treeMap.put("C", 15);  
        treeMap.put("D", 20);  
  
        // 将 TreeMap 转换为 List  
        List<Map.Entry<String, Integer>> list = new ArrayList<>(treeMap.entrySet());  
  
        // 根据值对 List 进行排序  
        list.sort(Map.Entry.comparingByValue());  
  
        // 创建一个新的 LinkedHashMap 来保持排序  
        Map<String, Integer> sortedMap = new LinkedHashMap<>();  
        for (Map.Entry<String, Integer> entry : list) {  
            sortedMap.put(entry.getKey(), entry.getValue());  
        }  
  
        // 输出排序后的 Map  
        for (Map.Entry<String, Integer> entry : sortedMap.entrySet()) {  
            System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
        }  
    }  
}

3.2 LinkedHashMap:LinkedHashMap 是 HashMap 的一个子类,它维护了一个双向链表来记录元素的插入顺序。因此,在遍历 LinkedHashMap 时,元素的顺序就是它们被插入的顺序。虽然 LinkedHashMap 本身不直接提供排序功能,但可以通过在遍历时使用 Collections.sort() 方法对键值对进行排序
3.3 转换为 List 进行排序将 Map 的键值对转换为 List,然后对 List 进行排序。这种方法可以自定义排序规则,但需要手动实现比较器(Comparator)。排序完成后,可以再将排序后的 List 转换回 Map。
3.4 使用 Stream API 进行排序:Java 8 引入了 Stream API,可以方便地对集合进行各种操作,包括排序。可以通过将 Map 的键值对转换为 Stream,然后使用 sorted() 方法进行排序。排序完成后,可以再将 Stream 转换回 Map。

import java.util.*;  
import java.util.stream.Collectors;  
  
public class MapSortingWithStreamAPI {  
    public static void main(String[] args) {  
        // 创建一个 HashMap  
        Map<String, Integer> map = new HashMap<>();  
        map.put("A", 10);  
        map.put("B", 5);  
        map.put("C", 15);  
        map.put("D", 20);  
  
        // 使用 Stream API 对值进行排序,并收集到 LinkedHashMap 以保持排序  
        Map<String, Integer> sortedMap = map.entrySet().stream()  
                .sorted(Map.Entry.comparingByValue()) // 根据值排序  
                .collect(Collectors.toMap(  
                        Map.Entry::getKey, // 键的映射函数  
                        Map.Entry::getValue, // 值的映射函数  
                        (oldValue, newValue) -> oldValue, // 当键冲突时的合并函数  
                        LinkedHashMap::new // 使用 LinkedHashMap 保持插入顺序  
                ));  
  
        // 输出排序后的 Map  
        sortedMap.forEach((key, value) -> System.out.println("Key = " + key + ", Value = " + value));  
    }  
}

上述代码中:
a. 将Map转换为一个Stream,然后使用sorted()方法对Stream中的元素进行排序。排序的依据是Map.Entry的值。
b. 使用collect()方法和Collectors.toMap()收集器将排序后的Stream转换回Map。使用LinkedHashMap作为结果Map,因为LinkedHashMap会按照插入顺序保持元素的顺序。
c. 如果Map中有多个具有相同值的键,Collectors.toMap()的合并函数将决定保留哪个键。在上述代码中,选择了保留旧的键(oldValue)。
d. Stream API的并行处理能力,这种方法在处理大型数据集时可能比传统的排序方法更高效。是否使用并行流,也取决于具体的数据集和硬件环境。在使用并行流(parallelStream())时,需要注意线程安全问题以及并行处理可能带来的额外开销。

Map的多重排序

对Map进行多重排序(即根据多个条件进行排序),可以使用Stream API结合Comparator.thenComparing()。

import java.util.*;  
import java.util.stream.Collectors;  
  
public class MultiLevelMapSorting {  
    public static void main(String[] args) {  
        // 创建一个 HashMap  
        Map<String, Person> map = new HashMap<>();  
        map.put("A", new Person("Alice", 25));  
        map.put("B", new Person("Bob", 20));  
        map.put("C", new Person("Charlie", 30));  
        map.put("D", new Person("David", 25));  
  
        // 使用 Stream API 进行多重排序  
        List<Person> sortedList = map.entrySet().stream()  
                .map(Map.Entry::getValue) // 将 Map.Entry 转换为 Person 对象  
                .sorted(Comparator.comparing(Person::getLastName) // 首先按 lastName 排序  
                        .thenComparing(Person::getFirstName) // 如果 lastName 相同,则按 firstName 排序  
                        .thenComparingInt(Person::getAge)) // 如果 firstName 也相同,则按 age 排序  
                .collect(Collectors.toList()); // 收集到 List 中  
  
        // 如果你想要保持排序后的顺序,可以使用 LinkedHashMap  
        Map<String, Person> sortedMap = sortedList.stream()  
                .collect(Collectors.toMap(  
                        person -> String.valueOf(sortedList.indexOf(person)), // 使用索引作为键  
                        person -> person,  
                        (oldValue, newValue) -> oldValue, // 如果键冲突,保留旧值  
                        LinkedHashMap::new // 使用 LinkedHashMap 保持插入顺序  
                ));  
  
        // 输出排序后的 Map  
        sortedMap.forEach((key, person) -> System.out.println("Name: " + person.getFirstName() + " " + person.getLastName() + ", Age: " + person.getAge()));  
    }  
  
    static class Person {  
        private String firstName;  
        private String lastName;  
        private int age;  
  
        public Person(String firstName, String lastName, int age) {  
            this.firstName = firstName;  
            this.lastName = lastName;  
            this.age = age;  
        }  
  
        public String getFirstName() {  
            return firstName;  
        }  
  
        public String getLastName() {  
            return lastName;  
        }  
  
        public int getAge() {  
            return age;  
        }  
    }  
}

在上述代码中:

  1. 定义了一个Person类,它包含firstName、lastName和age三个属性。通过创建了一个Map,其中键是字符串,值是Person对象。然后,使用Stream API对Map中的Person对象进行多重排序:首先按lastName排序,然后按firstName排序,最后按age排序。排序后的结果收集到一个List中。
  2. 为了保持排序后的顺序,我们将排序后的List转换回Map,其中键是List中元素的索引,值是原始的Person对象,使用LinkedHashMap来确保插入顺序与排序顺序一致。
  3. 上述代码中的排序是稳定的,即对于具有相同排序值的元素,它们在排序后的集合中的相对顺序与排序前的相对顺序相同。这是通过Collectors.toMap()的合并函数实现的,该函数保留了旧的值(即先遇到的元素)。
  4. 对于更复杂的排序场景,可以继续链式调用thenComparing()方法,添加更多的排序条件。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1439194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

提速MySQL:数据库性能加速策略全解析

提速MySQL&#xff1a;数据库性能加速策略全解析 引言理解MySQL性能指标监控和评估性能指标索引优化技巧索引优化实战案例 查询优化实战查询优化案例分析 存储引擎优化InnoDB vs MyISAM选择和优化存储引擎存储引擎优化实例 配置调整与系统优化配置调整系统优化优化实例 实战案例…

NAT——网络地址转换、NAPT

网络地址转换 NAT (Network Address Translation) 1994 年提出。 需要在专用网连接到互联网的路由器上安装 NAT 软件。 装有 NAT 软件的路由器叫做 NAT路由器&#xff0c;它至少有一个有效的外部全球 IP 地址。 所有使用本地地址的主机在和外界通信时&#xff0c;都要在 NA…

【python绘图】爱心、樱花树、饼图、折线图、雷达图

一、爱心 import turtledef curvemove():for i in range(200):turtle.speed(0)turtle.right(1) # 光标向右偏1度turtle.forward(1)# 前进1pxturtle.penup() turtle.goto(0, -70) turtle.pendown()turtle.color(red) turtle.begin_fill() turtle.left(140) turtle.forward(111…

计算机网络-无线通信技术与原理

一般我们网络工程师接触比较多的是交换机、路由器&#xff0c;很少涉及到WiFi和无线设置&#xff0c;但是呢在实际工作中一般企业也是有这些需求的&#xff0c;这就需要我们对于无线的一些基本配置也要有独立部署能力&#xff0c;今天来简单了解一下。 一、无线网络基础 1.1 无…

[设计模式Java实现附plantuml源码~行为型]请求的链式处理——职责链模式

前言&#xff1a; 为什么之前写过Golang 版的设计模式&#xff0c;还在重新写Java 版&#xff1f; 答&#xff1a;因为对于我而言&#xff0c;当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言&#xff0c;更适合用于学习设计模式。 为什么类图要附上uml 因为很…

详解各种LLM系列|LLaMA 1 模型架构、预训练、部署优化特点总结

作者 | Sunnyyyyy 整理 | NewBeeNLP https://zhuanlan.zhihu.com/p/668698204 后台留言『交流』&#xff0c;加入 NewBee讨论组 LLaMA 是Meta在2023年2月发布的一系列从 7B到 65B 参数的基础语言模型。LLaMA作为第一个向学术界开源的模型&#xff0c;在大模型爆发的时代具有标…

基于Springboot的足球社区管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的足球社区管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

二分算法--模板及原理总结

二分答案 首先我们看这个图&#xff1a; 我们需要二分的答案就是这个临界点x。 什么情况下可以使用二分呢&#xff1a; 具有单调性&#xff08;单调递增&#xff0c;单调递减&#xff09;&#xff0c;二段性&#xff08;整个区间一分为二&#xff0c;一段区间满足&#xff0c;一…

嵌入式学习之Linux入门篇笔记——7,Linux常用命令第二部分

配套视频学习链接&#xff1a;http://【【北京迅为】嵌入式学习之Linux入门篇】 https://www.bilibili.com/video/BV1M7411m7wT/?p4&share_sourcecopy_web&vd_sourcea0ef2c4953d33a9260910aaea45eaec8 目录 1.mkdir 命令 2.rmdir 3.rm 命令 4.touch 命令 5.clear…

【Git教程】(一)基本概念 ——工作流、分布式版本控制、版本库 ~

Git教程 基本概念 1️⃣ 为什么要用 Git2️⃣ 为什么要用工作流3️⃣ 分布式版本控制4️⃣ 版本库5️⃣ 简单的分支创建与合并&#x1f33e; 总结 在本章中&#xff0c;将介绍一个分布式版本控制系统的设计思路&#xff0c;以及它与集中式版本控制系统的不同之处。除此之外&am…

传输层DoS

传输层是国际标准化组织提出的开放系统互联参考模型&#xff08;OSI&#xff09;中的第四 层。该层协议为网络端点主机上的进程之间提供了可靠、有效的报文传送服务。 平时我们所谈论的拒绝服务攻击大多是基于TCP的&#xff0c;因为现实中拒绝服务的对象 往往都是提供HTTP服务的…

cmd卸载软件

如果使用的是Win 10&#xff0c;并且需要在磁盘内释放一些空间&#xff0c;可以直接在命令提示符里卸载不再使用的应用程序&#xff0c;和小编一起来看看详细的步骤吧。 步骤如下&#xff1a; 以管理员身份运行命令提示符来卸载程序。在Windows搜索框中&#xff0c;键入“ cm…

服务器运存使用率多少正常?

服务器运存使用率多少正常&#xff0c;这是一个相对主观的问题&#xff0c;因为服务器的正常运行不仅取决于运存使用率&#xff0c;还与服务器的工作负载、应用程序的特性和需求、服务器的配置和用途等多种因素有关。然而&#xff0c;一般来说&#xff0c;大多数服务器在运存使…

SpringCloud-Eureka原理分析

Eureka是Netflix开源的一款用于实现服务注册与发现的工具。在微服务架构中&#xff0c;服务的动态注册和发现是必不可少的组成部分&#xff0c;而Eureka正是为了解决这一问题而诞生的。 一、为何需要Eureka 在微服务架构中&#xff0c;服务之间的协同合作和高效通信是至关重要…

PostgreSql与Postgis安装

POstgresql安装 1.登录官网 PostgreSQL: Linux downloads (Red Hat family) 2.选择版本 3.安装 ### 源 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm ### 客户端 yum install postgresql14 ###…

机器学习:数据集划分笔记

数据集划分是机器学习中非常关键的步骤&#xff0c;能直接影响模型的训练效果和泛化能力。它的主要目的是为了评估模型对新数据的泛化能力&#xff0c;即模型在未见过的数据上能表现良好。 数据集通常被划分为三个部分&#xff1a;训练集&#xff08;Training set&#xff09;、…

oracle 启动命令以及ORA-01033问题处理、删除归档日志

1 启动数据库:startup 2 关闭数据库&#xff1a;Shutdown immediate 3 查看监听状态&#xff1a;lsnrctl status 4 启动监听&#xff1a;lsnrctl start 5 停止监听&#xff1a;lsnrctl stop 常见问题 1、在服务器重启后会出现&#xff0c;Oracle ORA-01033: ORAC…

CPP项目:Boost搜索引擎

1.项目背景 对于Boost库来说&#xff0c;它是没有搜索功能的&#xff0c;所以我们可以实现一个Boost搜索引擎来实现一个简单的搜索功能&#xff0c;可以更快速的实现Boost库的查找&#xff0c;在这里&#xff0c;我们实现的是站内搜索&#xff0c;而不是全网搜索。 2.对于搜索…

单片机接收PC发出的数据

#include<reg51.h> //包含单片机寄存器的头文件 /***************************************************** 函数功能&#xff1a;接收一个字节数据 ***************************************************/ unsigned char Receive(void) { unsigned char dat; …

Hadoop搭建(完全分布式)

节点分布&#xff1a; bigdata-masterbigdata-slave1bigdata-salve2 NameNode NodeManager NodeManager SecondaryNameNodeDataNodeDataNodeResourceManagerNodeManagerDataNode 目录 一、jdk安装&#xff1a; 二、hadoop安装 一、jdk安装&#xff1a; jdk-8u212链接&am…