写 Java 的「两数之和」时,我产生了如下两个问题:
1. 为什么用 Integer,不能用 int?
int是基本类型,Integer是它对应的包装类,属于引用类型。Java 泛型的类型参数必须是引用类型,所以:
Map<Integer,Integer>ht=newHashMap<>();// 正确// Map<int, int> ht = new HashMap<>(); // 编译错误操作哈希表时仍可以传入int,Java 会进行自动装箱:
ht.put(target-nums[i],i);// 两个 int 自动转换为 Integer取出的Integer放入int[]时,会进行自动拆箱:
returnnewint[]{i,ht.get(nums[i])};需要注意:对 null 拆箱会抛出 NullPointerException。Map.get()在键不存在时会返回null,因此取值后要确认非空,再当作int使用。
2. return null 和 return new int[0] 有什么区别?
两种写法都能编译,因为int[] 本身是引用类型,即使其中的元素是基本类型int。
| 写法 | 含义 | 读取.length | 遍历 | 访问[0] |
|---|---|---|---|---|
return null; | 没有数组对象 | 空指针异常 | 空指针异常 | 空指针异常 |
return new int[0]; | 存在一个长度为 0 的数组 | 得到 0 | 正常,执行 0 次 | 数组越界异常 |
返回null时,调用方需要先判断是否为空;返回空数组时,可以直接读取长度或遍历,但仍不能访问其中的元素。
new int[0]表示空数组,不是包含一个 0 的数组;后者应写为new int[]{0}。
3. 简单总结
如果“无解”是正常情况,返回空数组通常更方便;也可以约定返回
null,但调用方必须检查。若按约定必须有解,无解时也可以抛出异常。哈希表解法的平均时间复杂度为 O(n),空间复杂度为 O(n)。
对应知识点:Java泛型,自动拆装箱(Boxing & Unboxing)