Integer和int

Integer 和 int 的区别(通俗易懂版)

本质区别

  • int基本数据类型(Primitive Type),直接存储数值,效率高,但不能为 null
  • Integer包装类(Wrapper Class),是 int 的“对象版”,可以存储 null,并提供了一些额外方法(如类型转换、比较等)。

代码对比

(1) 声明与赋值

1
2
3
4
5
6
7
// int(基本类型)
int num1 = 10; // 直接存储数值
// num1 = null; // 错误!int不能为null

// Integer(包装类)
Integer num2 = 20; // 自动装箱(Java 5+)
Integer num3 = null; // 允许为null

(2)方法调用

1
2
3
4
5
6
7
8
// Integer 提供了一些实用方法
Integer num4 = 30;
System.out.println(num4.floatValue()); // 转换为float: 30.0
System.out.println(num4.compareTo(20)); // 比较大小(结果: 1,因为30 > 20)

// int 没有方法,只能直接计算
int num5 = 40;
// num5.floatValue(); // 错误!int不是对象,没有方法

(3)默认值

1
2
3
4
5
6
7
// int 默认值是 0
int defaultInt;
System.out.println(defaultInt); // 输出: 0

// Integer 默认值是 null
Integer defaultInteger;
// System.out.println(defaultInteger); // 编译错误(未初始化)

什么时候用 int?什么时候用 Integer?

✅ 使用 int 的场景

  • 高性能计算(如循环、数学运算)。
  • 不需要 null 值(比如方法的参数必须是一个有效数字)。
  • 数组或大量数据存储(int[] 比 Integer[] 更节省内存)。

例子:

1
2
3
4
5
// 计算1到100的和(用int效率更高)
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}

✅ 使用 Integer 的场景

  • 需要 null 表示“无值”(如数据库字段可能为 NULL)。
  • 泛型或集合(如 List< Integer >,因为集合不能存储基本类型)。
  • 调用对象方法(如 Integer.parseInt() 或 Integer.compare())。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
// 数据库查询结果可能为null
Integer userId = getUserFromDatabase(); // 可能返回null
if (userId != null) {
System.out.println("用户ID: " + userId);
} else {
System.out.println("用户不存在");
}

// 集合只能存储对象类型
List<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);

自动装箱(Auto-boxing)和拆箱(Unboxing)

Java 5+ 支持 int 和 Integer 自动转换:

1
2
3
4
5
// 自动装箱(int → Integer)
Integer num6 = 50; // 相当于 Integer.valueOf(50)

// 自动拆箱(Integer → int)
int num7 = num6; // 相当于 num6.intValue()

注意:自动装箱/拆箱可能影响性能(在极端高频计算时建议手动转换)。


总结

区别 int Integer
类型 基本数据类型 包装类(对象)
存储 直接存数值 存对象引用(可null)
效率 更高(无对象开销) 稍低(有对象开销)
默认值 0 null
适用场景 高性能计算、数组 集合、数据库字段、需要null的情况

简单记忆:

  • 用 int:算得快、不能空、存数组。
  • 用 Integer:要空值、进集合、调方法。

为什么还要用 int,而不是全部用 Integer?

虽然 Integer 功能更强大(支持 null、有方法、能用于泛型),但 int 仍然有不可替代的优势:

性能更高

  • int 是基本类型,直接存储在栈内存,访问速度快。
  • Integer 是对象,存储在堆内存,需要额外的内存开销(对象头、引用等),并且涉及自动装箱/拆箱(int ↔ Integer)时会有额外性能损耗。

示例:

1
2
3
4
5
6
7
8
9
10
11
// int(高效)
int sum = 0;
for (int i = 0; i < 100_000_000; i++) {
sum += i; // 直接计算,无额外开销
}

// Integer(较慢,因为涉及自动装箱/拆箱)
Integer sumObj = 0;
for (Integer i = 0; i < 100_000_000; i++) { // 每次循环都会装箱/拆箱
sumObj += i; // 相当于 sumObj = Integer.valueOf(sumObj.intValue() + i.intValue())
}

👉 在大量计算时(如科学计算、游戏引擎),int 比 Integer 快很多。


内存占用更小

  • int 固定占 4 字节
  • Integer 是对象,除了存储数值(4字节)外,还有对象头(约12-16字节)、对齐填充等,实际占用约 16~24 字节(取决于JVM实现)。

示例:

1
2
3
4
5
// int数组(紧凑,内存连续)
int[] primitiveArray = new int[1000]; // 约 4KB

// Integer数组(存储的是对象引用,额外开销大)
Integer[] objectArray = new Integer[1000]; // 约 16KB~24KB(每个元素是引用,实际对象在堆中)

👉 在存储大量数据(如图像处理、大数据计算)时,int[] 比 Integer[] 更节省内存。


为什么有 List< Integer > 而没有 List< int >?

Java 泛型的限制

Java 的泛型(如 List< T >不支持基本类型int, double 等),只能使用对象类型(Integer, Double 等)。这是由 Java 泛型的实现方式决定的(类型擦除)。

示例:

1
2
List<Integer> list = new ArrayList<>(); // 合法
// List<int> list = new ArrayList<>(); // 编译错误!

历史原因

Java 早期(1.5 之前)没有泛型,集合(如 ArrayList)只能存储 Object,所以必须用 Integer 代替 int。虽然后来引入了泛型,但为了兼容性,仍然不支持基本类型。

替代方案

如果一定要用基本类型的集合,可以使用 第三方库(如 FastUtilEclipse Collections)或 Java 8+ 的 IntStream

1
2
// 使用 IntStream(基本类型流)
IntStream.range(0, 100).toArray(); // 返回 int[]

什么时候用 int?什么时候用 Integer?

场景 推荐类型 原因
高性能计算、循环、数学运算 int 速度快,无额外内存开销
数组存储(如 int[] int 内存紧凑,访问高效
必须使用 null 的情况 Integer int 不能为 null,而 Integer 可以
集合(如 List< T > Integer 泛型不支持基本类型
数据库字段(可能为 NULL Integer 数据库的 INT NULL 对应 Java 的 Integer
调用对象方法(如 parseInt Integer 包装类提供了实用方法(如 Integer.parseInt(“123”)

总结

  1. int 更快更省内存,适合高性能计算和存储大量数据(如数组)。
  2. Integer 功能更强,支持 null、泛型、方法调用,适合集合、数据库交互等场景。
  3. List< int > 不存在,因为 Java 泛型不支持基本类型,只能用 List< Integer >

简单记忆:

  • 用 int:算得快、存得多、不能空。
  • 用 Integer:要空值、进集合、调方法。

算法题中 int 和 Integer 的常用知识点与代码示例

在算法题中,intInteger 的选择会直接影响代码的性能和功能实现。以下是常见场景和对应的代码示例:


基本运算与比较

直接计算(推荐用 int

1
2
3
4
5
6
7
8
9
10
11
// 计算斐波那契数列(用 int 更高效)
public int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int c = a + b;
a = b;
b = c;
}
return b;
}

比较大小(Integer.compare())

1
2
3
// 比较两个 Integer 对象
Integer x = 10, y = 20;
int result = Integer.compare(x, y); // -1(x < y)

集合与泛型(必须用 Integer)

List 排序

1
2
3
List<Integer> list = Arrays.asList(3, 1, 4, 2);
Collections.sort(list); // 升序排序
System.out.println(list); // [1, 2, 3, 4]

统计频率(HashMap)

1
2
3
4
5
6
int[] nums = {1, 2, 2, 3, 3, 3};
Map<Integer, Integer> freq = new HashMap<>();
for (int num : nums) {
freq.put(num, freq.getOrDefault(num, 0) + 1);
}
// 输出:{1=1, 2=2, 3=3}

自动装箱与拆箱的陷阱

循环中的性能问题

1
2
3
4
5
6
7
8
9
10
11
12
// 错误示范:频繁装箱拆箱(性能差)
Integer sum = 0;
for (int i = 0; i < 100000; i++) {
sum += i; // 等价于 sum = Integer.valueOf(sum.intValue() + i)
}

// 正确做法:先用 int 计算,最后转 Integer
int sumInt = 0;
for (int i = 0; i < 100000; i++) {
sumInt += i;
}
Integer sum = sumInt;

等号比较(== 陷阱)

1
2
3
4
5
6
7
Integer a = 100, b = 100;
System.out.println(a == b); // true(-128~127 缓存)

Integer c = 200, d = 200;
System.out.println(c == d); // false(超出缓存范围)
// 正确比较:用 equals() 或 intValue()
System.out.println(c.equals(d)); // true

数组与集合转换

int[] 转 List< Integer >

1
2
int[] arr = {1, 2, 3};
List<Integer> list = Arrays.stream(arr).boxed().collect(Collectors.toList());

List< Integer > 转 int[]

1
2
List<Integer> list = List.of(1, 2, 3);
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();

实用工具方法

字符串转数字

1
2
3
String s = "123";
int num = Integer.parseInt(s); // 字符串转 int
Integer numObj = Integer.valueOf(s); // 字符串转 Integer

进制转换

1
2
3
int decimal = 255;
String binary = Integer.toBinaryString(decimal); // "11111111"
String hex = Integer.toHexString(decimal); // "ff"

最大值/最小值常量

1
2
3
4
int max = Integer.MAX_VALUE; // 2147483647
int min = Integer.MIN_VALUE; // -2147483648
// 用于避免整数溢出(如二分查找)
int mid = left + (right - left) / 2; // 代替 (left + right) / 2

总结表格

场景 推荐类型 代码示例
数学运算/循环 int for (int i = 0; i < n; i++)
集合存储(List/Map) Integer List< Integer> list = new ArrayList<>()
比较大小 Integer Integer.compare(a, b)
字符串转数字 int/Integer Integer.parseInt(“123”)
避免装箱拆箱 优先用 int int sum = 0;(而非 Integer sum = 0;

关键点:

  • 性能敏感(如循环、数组操作) → 用 int
  • 功能需求(如 null、集合) → 用 Integer
  • 注意自动装箱的开销,尤其在循环中!