Java学习 -- 可变参数与Collections工具类
一.可变参数
可变参数(Varargs)是Java 5引入的一项特性,它允许方法接受不定数量的参数。可变参数在简化API设计和处理不定数量参数时非常有用。
基本语法
可变参数使用三个点(...
)表示,必须作为方法参数列表中的最后一个参数:
public void methodName(Type... parameterName) {// 方法体 }
特点
- 类型安全:编译器会检查可变参数的类型
- 数组转换:可变参数在内部被转换为数组
- 零或多个参数:可以传递零个或多个指定类型的参数
- 最后声明:可变参数必须是方法参数列表中的最后一个参数
可变参数的优缺点
优点:
- 代码简洁:使用可变参数可以避免为不同数量的参数编写多个重载方法,减少代码量。
- 灵活性高:可以接受任意数量的参数,提高了方法的通用性。
缺点:
- 可能导致性能问题:由于可变参数本质上是一个数组,每次调用方法时都需要创建一个数组对象,可能会带来一定的性能开销。
- 容易产生歧义:在方法重载时,如果处理不当,可能会导致调用方法时产生歧义,增加代码的复杂性。
通过合理使用可变参数,可以使 Java 代码更加简洁和灵活,但在使用过程中需要遵循相关规则,并注意避免潜在的问题
示例代码
1. 基本使用
public class VarargsExample {// 计算任意数量整数的和public static int sum(int... numbers) {int total = 0;for (int num : numbers) {total += num;}return total;}public static void main(String[] args) {System.out.println(sum(1, 2, 3)); // 输出:6System.out.println(sum(10, 20, 30, 40)); // 输出:100System.out.println(sum()); // 输出:0(无参数)}
}
2. 与普通参数结合使用
public class VarargsWithOtherParams {// 打印消息,前缀可选,后跟任意数量的字符串public static void printMessage(String prefix, String... messages) {if (prefix != null && !prefix.isEmpty()) {System.out.print(prefix + ": ");}for (String msg : messages) {System.out.print(msg + " ");}System.out.println();}public static void main(String[] args) {printMessage("Warning", "Low", "memory"); // 输出:Warning: Low memory printMessage(null, "Hello", "World"); // 输出:Hello World printMessage("Error"); // 编译错误,缺少可变参数}
}
3. 可变参数与重载
使用可变参数时要小心方法重载
public class VarargsOverloading {// 方法1:接受一个String参数public static void print(String s) {System.out.println("String: " + s);}// 方法2:接受可变参数String数组public static void print(String... strings) {System.out.println("Varargs:");for (String s : strings) {System.out.println(s);}}public static void main(String[] args) {print("Hello"); // 调用方法1(更具体)print("Hello", "World"); // 调用方法2}
}
4.可以将数组作为可变参数传递
由于可变参数本质上是一个数组,因此可以直接将一个数组作为参数传递给带有可变参数的方法。
public class ArrayAsVarargsExample {public static void printNames(String... names) {for (String name : names) {System.out.print(name + " ");}System.out.println();}public static void main(String[] args) {String[] nameArray = {"Alice", "Bob", "Charlie"};// 将数组作为可变参数传递printNames(nameArray);}
}
注意事项
性能考虑:每次调用可变参数方法都会创建一个新数组,在频繁调用的性能敏感代码中应谨慎使用。
与泛型的兼容性:可变参数与泛型一起使用时可能会有警告,因为类型擦除可能导致堆污染(heap pollution):
public static <T> void dangerous(T... array) {Object[] oa = array; // 警告:未经检查的转换oa[0] = "Hello"; // 可能抛出ArrayStoreException
}
重载歧义:避免创建可能引起歧义的重载方法,如:
void method(String... args) {}
void method(String[] args) {} // 编译错误:重复方法
空值处理:可变参数可以接收null,也可以接收包含null的数组:
public static void process(String... strings) {if (strings == null) {System.out.println("参数为null");} else {System.out.println("参数数量: " + strings.length);}
}process(null); // 输出:参数为null
process((String[])null); // 输出:参数为null
process(new String[]{null}); // 输出:参数数量: 1
二.Collections工具类
基本概念
Collections 是 Java 集合框架中的一个工具类,位于 java.util
包下。它提供了一系列静态方法,用于对集合进行排序、查找、替换等操作,这些方法可以处理各种集合类型,如 List
、Set
、Map
等。
常用方法
排序方法
sort(List<T> list)
:对列表进行自然排序,要求列表中的元素实现 Comparable
接口。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class SortExample {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(3);list.add(1);list.add(2);Collections.sort(list);System.out.println("排序后的列表: " + list);}
}
sort(List<T> list, Comparator<? super T> c)
:使用指定的比较器对列表进行排序。
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;class Student {int id;String name;public Student(int id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {return "Student{id=" + id + ", name='" + name + "'}";}
}public class CustomSortExample {public static void main(String[] args) {List<Student> studentList = new ArrayList<>();studentList.add(new Student(2, "Alice"));studentList.add(new Student(1, "Bob"));// 按 id 排序Collections.sort(studentList, Comparator.comparingInt(s -> s.id));System.out.println("按 id 排序后的列表: " + studentList);}
}
查找方法
binarySearch(List<? extends Comparable<? super T>> list, T key)
:使用二分查找法在有序列表中查找指定元素。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class BinarySearchExample {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(1);list.add(2);list.add(3);int index = Collections.binarySearch(list, 2);System.out.println("元素 2 的索引: " + index);}
}
替换方法
replaceAll(List<T> list, T oldVal, T newVal)
:将列表中所有的旧元素替换为新元素。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class ReplaceAllExample {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("apple");list.add("banana");list.add("apple");Collections.replaceAll(list, "apple", "cherry");System.out.println("替换后的列表: " + list);}
}
三.可变参数与 Collections 工具类的结合使用
可变参数可以和 Collections
工具类的方法结合使用,例如创建一个可以接受任意数量元素的方法,并将这些元素添加到集合中。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class VarargsAndCollections {public static <T> List<T> createList(T... elements) {List<T> list = new ArrayList<>();Collections.addAll(list, elements);return list;}public static void main(String[] args) {List<String> stringList = createList("a", "b", "c");System.out.println("创建的字符串列表: " + stringList);List<Integer> intList = createList(1, 2, 3);System.out.println("创建的整数列表: " + intList);}
}
在上述代码中,createList
方法使用可变参数接受任意数量的元素,然后使用 Collections.addAll
方法将这些元素添加到列表中。