本文纲要
- 可变参数
1.1 需求引入:固定参数的方法
1.2 JDK 1.5 之前的解决方案:数组传参
1.3 可变参数语法与底层原理
1.4 可变参数的注意事项 - 创建不可变的集合
2.1List.of()– 不可变的 List
2.2Set.of()– 不可变的 Set
2.3Map.of()– 不可变的 Map
2.4Map.ofEntries()– 提高可读性的变体
2.5 结合集合构造器实现批量添加
可变参数
项目代码结构
myparameter/src/com/wb/variableparameter/
├── MyVariableParameter1.java
├── MyVariableParameter2.java
├── MyVariableParameter3.java
└── MyVariableParameter4.java
1 ) 需求引入:固定参数的方法
先从一个简单需求开始:定义一个方法,求两个数的和;再定义一个方法,求三个数的和。
这是我们最直观的写法 —— 重载多个不同参数数量的方法。
package com.wb.variableparameter;
public class MyVariableParameter1 {
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 30;
int sum1 = getSum(a, b);
System.out.println(sum1); // 30
int sum2 = getSum(a, b, c);
System.out.println(sum2); // 60
}
public static int getSum(int a, int b) {
return a + b;
}
public static int getSum(int a, int b, int c) {
return a + b + c;
}
}
但是,如果要计算 N 个数的和,N 不确定,形参的个数就无法事先定义。
2 ) JDK 1.5 之前的解决方案:数组传参
在 JDK 1.5 之前,想实现“参数个数可变”,只能把所有数据封装到一个数组中,方法接收一个数组参数。
package com.wb.variableparameter;
public class MyVariableParameter2 {
public static void main(String[] args) {
// 在JDK5之前,会把所有的数据都先放到一个数组中
// 我们自己定义的方法,形参只要写一个数组就可以了。
int[] arr = {1, 2, 3, 4, 5};
int sum1 = getSum(arr);
System.out.println(sum1); // 15
}
private static int getSum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
return sum;
}
}
这种方式可以解决问题,但是每次调用都需要手动创建数组并填充数据,代码比较繁琐。
3 ) 可变参数语法与底层原理
可变参数(Variable Arguments) 又称“变长参数”,它可以让我们在调用方法时传入任意个该类型的实参,而无需提前封装数组。
语法格式:
数据类型... 变量名
例如:int... arr
可变参数底层其实就是一个数组,接收的所有实参都会被自动封装到一个对应类型的数组中。
它省去的是我们手动 new 数组、放数据的步骤。
package com.wb.variableparameter;
/*
需求:定义一个方法求N个数的和
可变参数实现
*/
public class MyVariableParameter3 {
public static void main(String[] args) {
// 验证数组直接打印的格式
// int[] arr = {1,2,3,4,5};
// System.out.println(arr); // [I@... 和可变参数内部数组格式一致
int sum1 = getSum(1, 2, 3, 4, 5); // 直接传多个参数
System.out.println(sum1); // 15
}
public static int getSum(int... arr) {
// 拿到 arr 就是数组,可以随意遍历
// System.out.println(arr); // 验证底层是数组
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
return sum;
}
}
4 ) 可变参数的注意事项
- 可变参数在底层就是数组,可以用任何遍历数组的方式操作它。
- 如果一个方法有多个参数且包含可变参数,可变参数必须放在最后。
否则前面的其他参数就无法接收到数据,所有实参都会被可变参数“吃掉”。
错误写法:
public static int getSum(int... arr, int number) { // 编译错误!
}
正确写法:
public static int getSum(int number, int... arr) {
// number 接收第一个参数,arr 接收后面所有参数
}
示例代码(修改自 MyVariableParameter3,添加额外参数):
public static int getSum(int number, int... arr) {
int sum = number; // 先加上第一个固定参数
for (int i = 0; i < arr.length; i++) {
sum = sum + arr[i];
}
return sum;
}
创建不可变的集合
从 JDK 9 开始,List、Set、Map 接口中都增加了名为 of() 的静态工厂方法,它可以快速创建不可变(Immutable)的集合。
不可变集合:一旦创建,不能添加、删除、修改任何元素。
所有 of 方法的参数都是可变参数,使用起来非常方便。
项目代码结构
这一部分对应的是项目中的 MyVariableParameter4.java,包含 4 个演示方法。
myparameter/src/com/wb/variableparameter/
└── MyVariableParameter4.java
1 ) List.of() – 不可变的 List
// 创建不可变 List
List<String> list = List.of("a", "b", "c", "d");
System.out.println(list); // [a, b, c, d]
验证不可变性
// 以下任何修改操作都会抛出 UnsupportedOperationException
list.add("Q");
list.remove("a");
list.set(0, "A");
运行时会直接报错,例如:
Exception in thread "main" java.lang.UnsupportedOperationException
2 ) Set.of() – 不可变的 Set
// 创建不可变 Set
Set<String> set = Set.of("a", "b", "c", "d");
System.out.println(set); // [a, b, c, d]
特别注意:
Set 本身不允许重复元素,所以在使用 Set.of() 时若传入重复元素会直接抛出 IllegalArgumentException。
// 错误示例:包含重复元素 "a"
Set<String> set = Set.of("a", "b", "c", "d", "a"); // 抛出异常
3 ) Map.of() – 不可变的 Map
Map.of() 的参数需要按照 key1, value1, key2, value2, … 的形式依次传入。
Map<String, String> map = Map.of(
"zhangsan", "江苏",
"lisi", "北京",
"wangwu", "天津"
);
System.out.println(map); // {zhangsan=江苏, lisi=北京, wangwu=天津}
底层会将 “zhangsan” 和 “江苏” 视为一个键值对,依次类推。
4 ) Map.ofEntries() – 提高可读性的变体
当键值对较多时,Map.of() 的参数平铺写法可读性较差。
Map.ofEntries() 可以将每个键值对先封装成 Map.Entry 对象,再传入变长参数中,代码结构更清晰。
Map<String, String> map = Map.ofEntries(
Map.entry("zhangsan", "江苏"),
Map.entry("lisi", "北京")
);
System.out.println(map); // {zhangsan=江苏, lisi=北京}
Map.entry(k, v) 是一个静态方法,返回一个不可变 Entry 对象
5 ) 结合集合构造器实现批量添加
不可变集合虽然不能修改,但它可以配合集合的有参构造器,实现批量添加数据到可变集合中。
比如我们以前往 ArrayList 中添加多个元素,需要写很多行的 add():
// 传统方式:逐个添加,代码冗长
ArrayList<String> list2 = new ArrayList<>();
list2.add("aaa");
list2.add("bbb");
list2.add("ccc");
list2.add("ddd");
借助 List.of() 和 ArrayList 的构造器,可以一行搞定:
// 批量添加:先创建不可变集合,再传给 ArrayList 构造器
ArrayList<String> list3 = new ArrayList<>(List.of("a", "b", "c", "d"));
System.out.println(list3); // [a, b, c, d]
工作原理:
List.of("a", "b", "c", "d")创建一个不可变的List(底层使用可变参数,想传多少元素都可以)。new ArrayList<>(不可变List)通过构造器将这个集合中的所有元素一次性复制到新的ArrayList中- 最终得到一个可以自由增删改查的普通
ArrayList,同时代码量大幅减少。
同样的技巧也适用于 HashSet、HashMap 等其他集合。
Set<String> set = new HashSet<>(Set.of("x", "y", "z"));
Map<String, Integer> map = new HashMap<>(Map.of("one", 1, "two", 2));
总结
| 知识点 | 关键要点 |
|---|---|
| 可变参数 | 格式 数据类型…,底层是数组,必须放在参数列表末尾 |
| 不可变集合 | List.of / Set.of / Map.of / Map.ofEntries |
| 不可变集合的特点 | 创建后不能增、删、改,任何修改操作都会抛出异常 |
Set.of 限制 | 参数中不能有重复元素,否则抛异常 |
| 批量添加技巧 | 使用 new ArrayList<>(List.of(...)) 等,简化集合初始化 |
通过可变参数和不可变集合的配合使用,可以让 Java 代码更加简洁易读,尤其在集合初始化场景下效果显著。
1076

被折叠的 条评论
为什么被折叠?



