Java中的TreeMap

翻译自callicoder

Java中的TreeMap是基于红黑树的一种队Java Map接口的实现。TreeMap里的entry对象会以key的自然序,或者在创建TreeMap时自定义的Comparator排序。
TreeMap 是Java Collection框架的一部分。它实现了NavigableMap接口,后者继承自SortedMap接口。下面是TreeMap的阶层图。

阶层图
SortedMap接口提供了维持key的顺序的功能。NavigableMap接口则提供了根据Map导航的功能。比如,找到比给定的key恰好大或者小的entry,找到TreeMap 中第一个或最后一个entry等。
由于TreeMap 实现了NavigableMap接口,就有了NavigableMapSortedMap提供的功能。

下面是TreeMap的一些关键点:

  • TreeMap总会以key排序。要么以key的自然序(数字大小,字典序)排序,要么以提供的自定义的Comparator排序。
  • TreeMap 不能包含重复的key。
  • TreeMap不能以null为key,但可以把null作为value。
  • TreeMap是非同步的。所以在多线程环境访问TreeMap必须要显性地同步。

创建一个TreeMap

1. 简单的TreeMap

下面的例子展示了如何创建一个简单的TreeMap以及向其添加新的键值对。TreeMap中的entry会基于自然序排序。


import java.util.SortedMap;
import java.util.TreeMap;

public class CreateTreeMapExample {
    public static void main(String[] args) {
        // 创建一个TreeMap
        SortedMap<String, String> fileExtensions  = new TreeMap<>();

        // 添加新的键值对
        fileExtensions.put("python", ".py");
        fileExtensions.put("c++", ".cpp");
        fileExtensions.put("kotlin", ".kt");
        fileExtensions.put("golang", ".go");
        fileExtensions.put("java", ".java");

        //打印TreeMap (输出会根据key的顺序排序)
        System.out.println(fileExtensions);
    }

}

输出:

{c++=.cpp, golang=.go, java=.java, kotlin=.kt, python=.py}

2. 自定义比较器的TreeMap

下面的例子展示了如何创建一个自定义比较器的TreeMap,让entry以降序排序。

import java.util.Comparator;
import java.util.SortedMap;
import java.util.TreeMap;

public class CreateTreeMapCustomComparatorExample {
    public static void main(String[] args) {
        // 创建降序比较器的TreeMap
        SortedMap<String, String> fileExtensions = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s2.compareTo(s1);
            }
        });
        /*上面可简单写成new TreeMap<>(Comparator.reverseOrder());*/

        //  添加新的键值对
        fileExtensions.put("python", ".py");
        fileExtensions.put("c++", ".cpp");
        fileExtensions.put("kotlin", ".kt");
        fileExtensions.put("golang", ".go");
        fileExtensions.put("java", ".java");

        // 打印TreeMap (输出会以比较器的顺序排序)
        System.out.println(fileExtensions);

    }
}

输出:

{python=.py, kotlin=.kt, java=.java, golang=.go, c++=.cpp}

3. 大小写排序的TreeMap

        SortedMap<String, String> fileExtensions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
        /* 也可写成new TreeMap<>(new Comparator<String>() {
                @Override
                public int compare(String s1, String s2) {
                    return s1.compareToIgnoreCase(s2);
                }
            })
        */
        fileExtensions.put("PYTHON", ".py");
        fileExtensions.put("c++", ".cpp");
        fileExtensions.put("KOTLIN", ".kt");
        fileExtensions.put("Golang", ".go");
        System.out.println(fileExtensions);

输出

{c++=.cpp, Golang=.go, KOTLIN=.kt, PYTHON=.py}

访问TreeMap

下面的例子展示如何:

  • 获得TreeMap的size
  • 检查TreeMap是否有某个key
  • 获取TreeMap的第一个entry
  • 获取TreeMap的最后一个一个entry
  • 获取比给定key恰好小的entry
  • 获取比给定key恰好大的entry
import java.util.Map;
import java.util.TreeMap;

public class AccessEntriesFromTreeMapExample {
    public static void main(String[] args) {
        TreeMap<Integer, String> employees = new TreeMap<>();

        employees.put(1003, "Rajeev");
        employees.put(1001, "James");
        employees.put(1002, "Sachin");
        employees.put(1004, "Chris");

        System.out.println("Employees map : " + employees);

        // 获取TreeMap的size
        System.out.println("Total number of employees : " + employees.size());

        // 检查TreeMap是否有某个key
        Integer id = 1004;
        if(employees.containsKey(id)) {
        	//根据key找到对应value
            String name = employees.get(id);
            System.out.println("Employee with id " + id + " : " + name);
        } else {
            System.out.println("Employee does not exist with id : " + id);
        }

        // 获取TreeMap的第一个和最后一个`entry`
        System.out.println("First entry in employees map : " + employees.firstEntry());
        System.out.println("Last entry in employees map : " + employees.lastEntry());

        // 获取比给定key恰好小的`entry`
        Map.Entry<Integer, String> employeeJustBelow = employees.lowerEntry(1002);
        System.out.println("Employee just below id 1002 : " + employeeJustBelow);

        // 获取比给定key恰好大的`entry`
        Map.Entry<Integer, String> employeeJustAbove = employees.higherEntry(1002);
        System.out.println("Employee just above id 1002 : " + employeeJustAbove);
    }
}

输出

Employees map : {1001=James, 1002=Sachin, 1003=Rajeev, 1004=Chris}
Total number of employees : 4
Employee with id 1004 : Chris
First entry in employees map : 1001=James
Last entry in employees map : 1004=Chris
Employee just below id 1002 : 1001=James
Employee just above id 1002 : 1003=Rajeev

从TreeMap中移除entry

下面的例子展示了如何

  • 从TreeMap中根据key移除
  • 从TreeMap中根据key-value移除
  • 从TreeMap中移除第一个entry
  • 从TreeMap中移除最后一个entry
import java.util.Map;
import java.util.TreeMap;

public class RemoveEntriesFromTreeMapExample {
    public static void main(String[] args) {
        TreeMap<String, String> countryISOCodeMapping = new TreeMap<>();

        countryISOCodeMapping.put("India", "IN");
        countryISOCodeMapping.put("United States of America", "US");
        countryISOCodeMapping.put("China", "CN");
        countryISOCodeMapping.put("United Kingdom", "UK");
        countryISOCodeMapping.put("Russia", "RU");
        countryISOCodeMapping.put("Japan", "JP");

        System.out.println("CountryISOCodeMapping : " + countryISOCodeMapping);

        // 根据key移除
        String countryName = "Japan";
        String isoCode = countryISOCodeMapping.remove(countryName);
        if(isoCode != null) {
            System.out.println("Removed (" + countryName + " => " + isoCode + ") from the TreeMap. New TreeMap " + countryISOCodeMapping);
        } else {
            System.out.println(countryName + " does not exist, or it is mapped to a null value");
        }

        // 根据key-value移除
        countryName = "India";
        boolean isRemoved = countryISOCodeMapping.remove(countryName, "IA");
        System.out.println("Was the mapping removed for " + countryName + "? : " + isRemoved);

        // 从TreeMap中移除第一个entry
        Map.Entry<String, String> firstEntry = countryISOCodeMapping.pollFirstEntry();
        System.out.println("Removed firstEntry : " + firstEntry + ", New TreeMap : " + countryISOCodeMapping);

        // 从TreeMap中移除最后一个entry
        Map.Entry<String, String> lastEntry = countryISOCodeMapping.pollLastEntry();
        System.out.println("Removed lastEntry : " + lastEntry + ", New TreeMap : " + countryISOCodeMapping);
    }
}

输出

CountryISOCodeMapping : {China=CN, India=IN, Japan=JP, Russia=RU, United Kingdom=UK, United States of America=US}
Removed (Japan => JP) from the TreeMap. New TreeMap {China=CN, India=IN, Russia=RU, United Kingdom=UK, United States of America=US}
Was the mapping removed for India? : false
Removed firstEntry : China=CN, New TreeMap : {India=IN, Russia=RU, United Kingdom=UK, United States of America=US}
Removed lastEntry : United States of America=US, New TreeMap : {India=IN, Russia=RU, United Kingdom=UK}

总结

这篇文章中,你学到了什么是TreeMap,如何创建TreeMap,如何自定义TreeMap排序,如何从TreeMap中找到entry,以及如何从TreeMap中移除entry

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值