java map使用数字类型作为key的坑

本文通过一个具体的Java示例展示了当使用不同类型的包装类作为HashMap的键时可能出现的问题。特别是当预期的Integer键被Long键替代时,尽管不会引发错误,但会导致数据检索失败。
部署运行你感兴趣的模型镜像
看一个例子


import java.util.HashMap;
import java.util.Map;

public class MapTest {

@org.junit.Test
public void test() {
Map<Integer, Map<Integer, String>> big = new HashMap<Integer, Map<Integer,String>>();
for(int i = 0; i < 10; i++) {
Map<Integer, String> small = new HashMap<Integer, String>();
small.put(i, String.valueOf(i));
big.put(i, small);
}
System.out.println(big);

long key = 2L;
System.out.println(big.get(key));
int k2 = 2;
System.out.println(big.get(k2));
}
}


输出如下:

{0={0=0}, 1={1=1}, 2={2=2}, 3={3=3}, 4={4=4}, 5={5=5}, 6={6=6}, 7={7=7}, 8={8=8}, 9={9=9}, 10={10=10}}
null
{2=2}


可以看到,使用long型作为key并不会报错,只是遗憾的取不到数据。

HashMap#get(Obecect obj)方法使用的参数是Object类型,也就是使用任何参数都不会报错,在一般情况下,如果key是复杂对象,写代码时都能注意到。

不巧的是这个case里使用Integer类型作为key,而又用long类型去get,经过装箱后实际上是使用Long作为key查询,自然也就查不到数据。

修改的方式也比较简单,显式的修改参数类型。

System.out.println(big.get(Integer.valueOf(key)));

您可能感兴趣的与本文相关的镜像

Stable-Diffusion-3.5

Stable-Diffusion-3.5

图片生成
Stable-Diffusion

Stable Diffusion 3.5 (SD 3.5) 是由 Stability AI 推出的新一代文本到图像生成模型,相比 3.0 版本,它提升了图像质量、运行速度和硬件效率

<think>好的,用户现在想在Java中实现MapKey值排序的方法或代码示例。我需要根据之前的对话和提供的引用信息来生成回答。首先,回顾用户之前的问题和我的回答,用户已经了解过三种方法:TreeMap自动排序、Stream API转换和自定义排序规则。现在用户再次询问,可能需要更详细的步骤或更多方法。 看看用户提供的引用,引用[2]提到使用List的sort方法或Collections.sort对键进行排序,然后将结果存入LinkedHashMap。引用[3]展示了使用Stream流进行排序的代码示例。引用[5]提到了TreeMap的构造方法可以使用Comparator。而引用[4]比较了LinkedHashMap和HashMap的性能。 用户可能希望得到更全面的方法总结,包括之前提到的和引用中的其他方法。需要整合这些信息,确保覆盖所有可能的排序方式。例如,除了TreeMap、Stream API,还有使用List排序后转LinkedHashMap的方法。此外,自定义比较器可能需要更详细的例子,特别是处理不同类型的键,比如字符串或数字。 要注意用户的需求是Java中的实现,所以每种方法都需要对应的代码示例,并解释其原理和适用场景。比如,TreeMap适用于自动维护排序,而Stream和List方法适合对已有Map进行排序。另外,需要提到不同Map实现的特性,如LinkedHashMap保持插入顺序,TreeMap自然排序等。 可能还需要比较不同方法的性能,比如TreeMap的O(log n)插入和Stream的O(n log n)排序,帮助用户根据需求选择合适的方法。同时,处理自定义对象作为键的情况,需要实现Comparable接口或提供Comparator,这也是用户可能关心的问题。 最后,确保回答结构清晰,分点列出,每个方法都有代码示例和说明。还要注意用户提到的引用,正确标注来源,比如引用[2]中的List排序方法,引用[5]中的TreeMap构造器使用Comparator。同时,相关问题部分需要与排序相关,如按值排序、不同Map区别等,引导用户进一步学习。</think>在Java中实现Map按键排序有5种典型方法,以下是具体实现方案及代码示例: ### 一、TreeMap自然排序法(推荐方案) ```java Map<String, Integer> map = new TreeMap<>(); map.put("Zebra", 5); map.put("Apple", 1); map.put("Banana", 3); // 自动按键的字母顺序排序 System.out.println(map); // 输出:{Apple=1, Banana=3, Zebra=5} ``` 特性说明: - 底层采用红黑树数据结构 - 插入时自动维护排序,时间复杂度$O(log\ n)$[^5] - 默认使用自然顺序(Comparable接口实现) ### 二、List集合转换法(适用于已有HashMap) ```java Map<Integer, String> originMap = new HashMap<>(); originMap.put(300, "A"); originMap.put(100, "B"); originMap.put(200, "C"); // 转换为List进行排序 List<Map.Entry<Integer, String>> entryList = new ArrayList<>(originMap.entrySet()); Collections.sort(entryList, Map.Entry.comparingByKey()); // 创建有序Map Map<Integer, String> sortedMap = new LinkedHashMap<>(); for (Map.Entry<Integer, String> entry : entryList) { sortedMap.put(entry.getKey(), entry.getValue()); } System.out.println(sortedMap); // 输出:{100=B, 200=C, 300=A} ``` 优势:兼容所有Map实现类,排序过程可视化[^2] ### 三、Stream API排序法(Java8+) ```java Map<String, Integer> unorderedMap = Map.of( "Tokyo", 3800, "NewYork", 8500, "Paris", 2100 ); Map<String, Integer> orderedMap = unorderedMap.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (oldVal, newVal) -> oldVal, LinkedHashMap::new )); System.out.println(orderedMap); // 输出:{NewYork=8500, Paris=2100, Tokyo=3800} ``` 特点:函数式编程风格,时间复杂度$O(n\ log\ n)$[^3] ### 四、自定义排序规则 ```java // 按Key长度排序 Comparator<String> lengthComparator = Comparator .comparingInt(String::length) .thenComparing(Comparator.naturalOrder()); Map<String, Integer> customMap = new TreeMap<>(lengthComparator); customMap.put("Python", 1); customMap.put("Java", 2); customMap.put("C++", 3); System.out.println(customMap); // 输出:{C++=3, Java=2, Python=1} ``` ### 五、数值键特殊处理 ```java Map<String, Integer> numericMap = new HashMap<>(); numericMap.put("100", 1); numericMap.put("20", 2); numericMap.put("3", 3); // 将String类型Key转为数值排序 Map<String, Integer> sortedNumericMap = numericMap.entrySet().stream() .sorted(Comparator.comparingInt(e -> Integer.parseInt(e.getKey()))) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new )); System.out.println(sortedNumericMap); // 输出:{3=3, 20=2, 100=1} ``` **性能对比表**: | 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | |--------------------|------------|------------|--------------------------| | TreeMap | O(log n) | O(n) | 需要持续维护排序状态 | | List转换法 | O(n log n) | O(n) | 已有Map需要单次排序 | | Stream API | O(n log n) | O(n) | Java8+函数式编程环境 | | LinkedHashMap保持法| O(1) | O(n) | 仅需保持插入顺序时[^4] |
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值