博客
关于我
JAVA map排序实现
阅读量:766 次
发布时间:2019-03-23

本文共 4740 字,大约阅读时间需要 15 分钟。

Map排序方式总结

在编程实践中,Map数据结构常用于存储键值对的数据。在实际应用中,按键或按值排序Map时往往需要特定的处理方式。下面将介绍两种常用的Map排序方法:按键排序按值排序


1. 按键排序

理解与实现

按键排序是最常见的Map排序方式。需要使用JDK中的TreeMap数据结构,其默认行为就是以键的比较结果决定排序顺序。要实现自定义的按键排序,可以传递一个比较器参数。

实现代码

import java.util.TreeMap;
import java.util.Comparator;
public class MapSortDemo {
public static void main(String[] args) {
TreeMap
map = new TreeMap<>();
map.put("KFC", "kfc");
map.put("WNBA", "wnba");
map.put("NBA", "nba");
map.put("CBA", "cba");
TreeMap
resultMap = sortMapByKey(map); // 按Key排序
for (Map.Entry
entry : resultMap.entrySet()) {
System.out.println(entry.getKey() + " " + entry.getValue());
}
}
private static TreeMap
sortMapByKey(Map
map) {
if (map == null || map.isEmpty()) {
return null;
}
TreeMap
sortMap = new TreeMap<>(new MapKeyComparator()); sortMap.putAll(map); return sortMap; } private static class MapKeyComparator implements Comparator
{ @Override public int compare(String str1, String str2) { return str1.compareTo(str2); } } }

代码解释

  • TreeMap:用于存储键值对的 TreeMap 实现,其默认排序方式是按键升序。
  • 自定义比较器:通过实现 Comparator接口,定义了键的比较规则。
  • sortMapByKey 方法:根据输入Map创建一个新的TreeMap并放入所有元素,然后返回排序后的Map。

效果展示

执行代码后,输出的结果会按照键的升序排列:

CBA cba
KFC kfc
NBA nba
WNBA wnga

2. 按值排序

理解与实现

按值排序相对复杂一些。因为Map没有直接的按值排序方法,常见的做法是将Map转换为列表,使用Collections.sort对列表的元素进行排序。排序完成后,再将元素重新放入Map中。

实现步骤

  • 将Map中的所有条目提取出来,存储在一个条目列表中。
  • 对列表进行自定义排序,根据值的大小决定排序顺序。
  • 创建一个新的LinkedHashMap(以保持插入顺序)。
  • 将排序后的条目逐个添加到新Map中。
  • 实现代码

    import java.util.Collections;
    import java.util.LinkedHashMap;
    import java.util.ArrayList;
    import java.util.Comparator;
    import java.util.Map.Entry;
    public class MapSortDemo {
    public static void main(String[] args) {
    TreeMap
    map = new TreeMap<>();
    map.put("KFC", "kfc");
    map.put("WNBA", "wnba");
    map.put("NBA", "nba");
    map.put("CBA", "cba");
    Map
    resultMap = sortMapByValue(map); // 按Value排序
    for (Map.Entry
    entry : resultMap.entrySet()) {
    System.out.println(entry.getKey() + " " + entry.getValue());
    }
    }
    private static Map
    sortMapByValue(Map
    oriMap) {
    if (oriMap == null || oriMap.isEmpty()) {
    return null;
    }
    LinkedHashMap
    sortedMap = new LinkedHashMap<>(); ArrayList
    > entryList = new ArrayList<>(oriMap.entrySet()); Collections.sort(entryList, new MapValueComparator()); Iterator
    > iter = entryList.iterator(); Map.Entry
    tmpEntry = null; while (iter.hasNext()) { tmpEntry = iter.next(); sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue()); } return sortedMap; } private static class MapValueComparator implements Comparator
    > { @Override public int compare(Map.Entry
    me1, Map.Entry
    me2) { return me1.getValue().compareTo(me2.getValue()); } } }

    代码解释

    • sortMapByValue 方法:将输入Map转换为列表并排序,最后按顺序存储到新Map中。
    • Comparator接口:定义了根据值的比较规则,返回值的比较结果决定排序顺序。

    效果展示

    排序后输出的结果会按照值的升序排列:

    CBA cba
    KFC kfc
    NBA nba
    WNBA wnga

    常见问题与解答

    1. 为什么按键排序更简单?

    因为TreeMap本身就是按键排序的结构,只需传递比较器即可。无需额外处理键与值之间的关系。

    2. 如何实现按值所需的Comparator?

    可以将Map转换为条目列表,对列表应用按照值排序的比较器,最后再进行存储。如上文的MapValueComparator实现。

    3. 为什么选择LinkedHashMap?

    因为Collections.sort会重新排列列表中的元素,而LinkedHashMap可以根据插入顺序保持元素的顺序,这是实现按值排序的关键。


    实际案例:条形码排序

    在仓库管理中,条形码的排列可能需要满足特定条件。例如,确保条形码中相邻的两个不全相同。以下是一个常见的解决方案:

    import java.util.LinkedHashMap;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Map.Entry;
    public class Solution {
    public int[] rearrangeBarcodes(int[] barcodes) {
    int[] res = new int[barcodes.length];
    int j = 0;
    Map
    map = new LinkedHashMap<>();
    for (int i = 0; i < barcodes.length; i++) {
    map.put(barcodes[i], map.getOrDefault(barcodes[i], 0) + 1);
    }
    ArrayList
    > list = new ArrayList<>(map.entrySet());
    Collections.sort(list, new Comparator
    >() {
    @Override
    public int compare(Map.Entry
    m1, Map.Entry
    m2) { return -Integer.compare(m1.getValue(), m2.getValue()); } }); Iterator
    > iter = list.iterator(); Map.Entry
    tmpEntry = null; while (iter.hasNext()) { tmpEntry = iter.next(); int num = tmpEntry.getValue(); int n = tmpEntry.getKey(); // 根据具体需求调整排序逻辑 for (int i = 0; i < num; i++) { res[j] = n; j += 2; if (j > barcodes.length) { j = 0; } } } return res; } }

    解释

  • 统计频率:将条形码存储到LinkedHashMap中,统计每个条形码的数量。
  • 排序:将条目排序,优先根据数量从大到小排列。
  • 重建数组:根据排序后的列表,逐个填充结果数组,避免相邻重复。
  • 这种方法可以确保条形码的排列符合特定规则,同时保持一定的可读性和性能。


    总结

    通过以上方法,我们可以轻松地对Map数据进行按键或按值排序。如果需要更复杂的排序规则,可以根据具体需求扩展比较器逻辑。这些方法在实际开发中能够帮助我们高效地处理各种数据排序问题。

    转载地址:http://uiqzk.baihongyu.com/

    你可能感兴趣的文章
    MySQL 高性能优化规范建议
    查看>>
    mysql 默认事务隔离级别下锁分析
    查看>>
    Mysql--逻辑架构
    查看>>
    MySql-2019-4-21-复习
    查看>>
    mysql-5.6.17-win32免安装版配置
    查看>>
    mysql-5.7.18安装
    查看>>
    MySQL-Buffer的应用
    查看>>
    mysql-cluster 安装篇(1)---简介
    查看>>
    mysql-connector-java.jar乱码,最新版mysql-connector-java-8.0.15.jar,如何愉快的进行JDBC操作...
    查看>>
    mysql-connector-java各种版本下载地址
    查看>>
    mysql-EXPLAIN
    查看>>
    MySQL-Explain的详解
    查看>>
    mysql-group_concat
    查看>>
    MySQL-redo日志
    查看>>
    MySQL-【1】配置
    查看>>
    MySQL-【4】基本操作
    查看>>
    Mysql-丢失更新
    查看>>
    Mysql-事务阻塞
    查看>>
    Mysql-存储引擎
    查看>>
    mysql-开启慢查询&所有操作记录日志
    查看>>