Collections
java.utils.Collections 是集合工具类,用来对集合进行操作。Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。
常用方法:
public static <T> boolean addAll(Collection<T> c, T...elements)
: 将所有指定元素添加到指定 collection 中
参数列表中的
T...elements
表示可变参数,当方法的参数数据类型已经确定,但参数的个数不确定就可以使用可变参数。
- 格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型... 变量名){
// 方法体
}
- 原理:可变参数的底层是一个数组,根据传递参数的个数不同会创建不同长度的数组来存储这些参数;传递的参数格式可以是0到多个
可变参数的使用示例:
```java import java.util.Arrays;
public class argsMain { public static void main(String[] args) { int[] array = new int[]{1,2,3}; System.out.println(add(array)); // 6
int[] array1 = new int[]{1,2,3,4,5,6,7};
System.out.println(add(array1)); // 28
}
public static int add(int... array){
System.out.println(array); // [I@1b6d3586, 底层是一个数组
System.out.println(Arrays.toString(array)); // [1, 2, 3]
int sum = 0;
for(int ele : array){
sum += ele;
}
return sum;
}
}
> **NOTE:**
> -
一个方法的参数列表只能用一个可变参数
> -
如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
> -
特殊写法,它可以接收任意数据类型的数据:
```java
public static void method(Object... obj){
// 方法体
}
Python中同样可以使用可变参数:
- 当在方法的参数列表中声明类似于
*args
的参数时,从此处开始直到结束的所有位置参数都将被收集到一个成为param
的元组中- 当在方法的参数列表中声明类似于
**args
的参数时,从此处开始直到结束的所有位置参数都将被收集到一个成为param
的字典中```python def method(a, numbers, **phonebook): print(‘a’, a) print (‘-‘ 10)
print (numbers) # (1, 2, 3)
for i in numbers:
print(i)
print ('-' * 10)
print(phonebook) # {'Jack': 1123, 'John': 2231, 'Inge': 1560}
for k, v in phonebook.items():
print(k,v)
# output:
# a 10
# ----------
# 1
# 2
# 3
# ----------
# Jack 1123
# John 2231
# Inge 1560
if name == “main“: method(10,1,2,3,Jack=1123,John=2231,Inge=1560)
- `public static void reverse(List<?> list)`: 反转指定列表List中元素的顺序
- `public` `static` `void` `shuffle(List list)`: 将集合中的元素打乱
- `public static int frequency(Collection<?> c,Object o)`: 返回指定集合中指定元素的出现次数
- `public static void swap(List<?> list,int i,int j)`: 将指定 list 集合中的 i 处元素和 j 处元素进行交换
```java
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
// addAll()
System.out.println(list1); // []
Collections.addAll(list1, 1,2,3,4,5);
System.out.println(list1); // [1, 2, 3, 4, 5]
Collections.addAll(list2, "abc", "ccb", "bde");
System.out.println(list2); // [abc, ccb, bde]
// reverse()
Collections.reverse(list1);
System.out.println(list1); // [5, 4, 3, 2, 1]
// shuffle()
Collections.shuffle(list1);
System.out.println(list1); // [1, 4, 2, 3, 5]
// swap()
Collections.swap(list1, 0, list1.size() - 1);
System.out.println(list1); //[1, 4, 3, 2, 5]
// frequency()
System.out.println(Collections.frequency(list1, 1)); // 1
public static <T> void sort(List<T> list)
: 将集合中的元素按照默认规则进行排序,默认为升序排列,而且被排序的集合里面存储的而元素必须实现Comparable
,重写接口中的compareTo
方法。 ```java package collections;
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList
// addAll()
System.out.println(list1); // []
Collections.addAll(list1, 1,2,3,4,5);
System.out.println(list1); // [1, 2, 3, 4, 5]
Collections.addAll(list2, "abc", "ccb", "bde");
System.out.println(list2); // [abc, ccb, bde]
Collections.sort(list1);
Collections.sort(list2);
System.out.println(list1); // [1, 2, 3, 4, 5]
System.out.println(list2); // [abc, bde, ccb]
}
}
<br />例如在String中实现了`Comparable<String>`接口,并重写了`compareTo`方法:
```java
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
...
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
}
如果我们想要对自定义的类使用sort方法,同样需要实现Comparable<String>
接口,并重写compareTo
方法。假设现在自定义了一个Person类如下所示,我们实现了接口并重写了其中的compareTo
方法:
public class Person implements Comparable<Person>{
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public int compareTo(Person o) {
// 按照age大小升序
// 降序:o.getAge() - this.Age()
return this.getAge() - o.getAge();
}
}
那么我们就可以调用包含Person对象的Collections中的sort方法。
package collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Person> list3 = new ArrayList<>();
list3.add(new Person(22,"Forlogen"));
list3.add(new Person(20, "kobe"));
System.out.println(list3); // [Person{age=22, name='Forlogen'}, Person{age=20, name='kobe'}]
Collections.sort(list3);
System.out.println(list3); // [Person{age=20, name='kobe'}, Person{age=22, name='Forlogen'}]
}
}
public static <T> void sort(List<T> list, Comparator<? super T>)
: 将集合中的元素按照指定的规则进行排序 ```java import java.util.ArrayList; import java.util.Collections; import java.util.Comparator;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList
// 新建一个Comparator并重写其中的compare方法
Collections.sort(list2, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
// 按照字符串中中索引为1的元素升序排列
return o1.charAt(1) - o2.charAt(1);
}
});
System.out.println(list2); // [abc, ccb, bde]
}
}
<br />那么两种sort方法中的Comparable和Comparator有什么区别呢?
- Comparable:自己和传入的参数进行比较,使用时需要实现`Comparable<String>`接口,并重写`compareTo`方法,它相当于一个内部的排序器
- Comparator:自定义的排序规则来比较两个对象,它相当于一个外部的排序器
-
`public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)`: 在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定
-
`public static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c)`: 在List集合中查找某个元素的下标,但是List的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定
```java
package collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
ArrayList<String> list2 = new ArrayList<>();
Collections.addAll(list1, 1, 5, 7, 2, 10, 3);
System.out.println(Collections.binarySearch(list1, 10)); // 4
System.out.println(Collections.binarySearch(list1, 1)); // 0
Collections.addAll(list2, "abc", "ccb", "bde");
int i = Collections.binarySearch(list2, "abc", new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.charAt(1) - o2.charAt(1);
}
});
System.out.println(i); // 0
}
}
- …
Collection和Collections的区别
- java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式
- java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化