Java - Map 的区别 & 自定义 Map 的排序

本文详细介绍了Java中的HashMap、LinkedHashMap和TreeMap的区别。HashMap是最常用的,提供快速访问,但不保证顺序。LinkedHashMap按照插入顺序排序,可以按访问次数排序。TreeMap按照键的自然顺序或自定义比较器排序。文章还提供了按Key和Value排序Map的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Map主要用于存储健值对,根据键得到值,因此不允许键重复,但允许值重复。如HashMap最多只允许一条记录的键为Null,允许多条记录的值为 Null;

HashMap

Hashmap 是一个最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。
HashMap最多只允许一条记录的键为Null,允许多条记录的值为 Null。
HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。

  • 非编程顺序,且可能因使用而改变;
  • 具有很快的访问速度;
  • HashMap不支持线程的同步,即任一时刻可以有多个线程同时写HashMap,可能会导致数据的不一致。如果需要同步,可以用 Collections的synchronizedMap方法使HashMap具有同步的能力,或者使用ConcurrentHashMap。

LinkedHashMap

LinkedHashMap是HashMap子类。

  • 插入顺序,也可以在构造时用参数,按照应用次数排序;
  • 遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

TreeMap

  • 实现SortMap接口,根据键排序,默认是按键值的升序排序,也可以指定排序的比较器;

自定义比较器

按 Key 排序

使用 TreeMap 的构造函数,传入比较器,再 putAll 将要排序的 Map 的所有元素放进去,所得的 TreeMap 即为 Map 按 Key 排序的结果。

TreeMap 的构造函数如下:

TreeMap()
TreeMap(Comparator<? super K> comparator)
TreeMap(Map<? extends K, ? extends V> m)
TreeMap(SortedMap<K, ? extends V> m)

使用第二个构造函数所用的比较器如下:

class MapKeyComparator implements Comparator<String> {
    @Override
    public int compare(String o1, String o2) {
        return o1.compareTo(o2);
    }
}

Map 的排序方法如下:

private Map<String, String> sortMapByKey(Map<String, String> map) {
    Map<String, String> sortMap = new TreeMap<>(new MapKeyComparator());
    sortMap.putAll(map);
    return sortMap;
}

完整示例如下:

public class MapSortDemo {
    public static void main(String[] args) {
        Map<String, String> map = new TreeMap<>();
        map.put("KFC", "kfc");
        map.put("WNBA", "wnba");
        map.put("NBA", "nba");
        map.put("CBA", "cba");

        MapSortDemo mapSortDemo = new MapSortDemo();
        Map<String, String> resultMap = mapSortDemo.sortMapByKey(map);
        for (Map.Entry<String, String> entry: resultMap.entrySet()) {
            System.out.println(entry.getKey() + "   " + entry.getValue());
        }
    }

    private Map<String, String> sortMapByKey(Map<String, String> map) {
        Map<String, String> sortMap = new TreeMap<>(new MapKeyComparator());
        sortMap.putAll(map);
        return sortMap;
    }

    class MapKeyComparator implements Comparator<String> {
        @Override
        public int compare(String o1, String o2) {
            return o1.compareTo(o2);
        }
    }
}

结果如下:

CBA   cba
KFC   kfc
NBA   nba
WNBA   wnba

按 Value 排序

按值排序就相对麻烦些了,貌似没有直接可用的数据结构能处理类似需求。

可以将 Map 转成 List,使用 Collections.sort 带比较器参数的方法可以将传入的 list 按比较器规则排序:

public static <T> void sort(@NotNull java.util.List<T> list,
                            @Nullable java.util.Comparator<? super T> c)

Collections.sort 所用比较器如下:

class MapValueComparator implements Comparator<Map.Entry<String, String>> {
    @Override
    public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
        return o1.getValue().compareTo(o2.getValue());
    }
}

之后将排序好的 list 遍历放进新的 Map 中即可。

Map 的排序方法如下:

private Map<String, String> sortMapByValue(Map<String, String> map) {
    Map<String, String> sortMap = new TreeMap<>();

    List<Map.Entry<String, String>> entryList = new ArrayList<>(map.entrySet());
    Collections.sort(entryList, new MapValueComparator());

    Iterator<Map.Entry<String, String>> iter = entryList.iterator();
    Map.Entry<String, String> tmpEntry = null;
    while (iter.hasNext()) {
        tmpEntry = iter.next();
        sortMap.put(tmpEntry.getKey(), tmpEntry.getValue());
    }

    return sortMap;
}

完整示例如下:

public class MapSortDemo {
    public static void main(String[] args) {
        Map<String, String> map = new TreeMap<>();
        map.put("KFC", "kfc");
        map.put("WNBA", "wnba");
        map.put("NBA", "nba");
        map.put("CBA", "cba");

        MapSortDemo mapSortDemo = new MapSortDemo();
        Map<String, String> resultMap = mapSortDemo.sortMapByValue(map);
        for (Map.Entry<String, String> entry: resultMap.entrySet()) {
            System.out.println(entry.getKey() + "   " + entry.getValue());
        }
    }

    private Map<String, String> sortMapByValue(Map<String, String> map) {
        Map<String, String> sortMap = new TreeMap<>();

        List<Map.Entry<String, String>> entryList = new ArrayList<>(map.entrySet());
        Collections.sort(entryList, new MapValueComparator());

        Iterator<Map.Entry<String, String>> iter = entryList.iterator();
        Map.Entry<String, String> tmpEntry = null;
        while (iter.hasNext()) {
            tmpEntry = iter.next();
            sortMap.put(tmpEntry.getKey(), tmpEntry.getValue());
        }

        return sortMap;
    }

    class MapValueComparator implements Comparator<Map.Entry<String, String>> {
        @Override
        public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
            return o1.getValue().compareTo(o2.getValue());
        }
    }
}

结果如下:

CBA   cba
KFC   kfc
NBA   nba
WNBA   wnba

来自 https://www.cnblogs.com/zhujiabin/p/6164826.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值