Collections
java.utils.Collections 是集合工具类,用来对集合进行操作。Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。
常用方法:
-
public static <T> boolean addAll(Collection<T> c, T...elements): 将所有指定元素添加到指定集合中参数列表中的
T...elements表示可变参数,当方法的参数数据类型已经确定,但参数的个数不确定就可以使用可变参数。-
格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型... 变量名){ // 方法体 } -
原理:可变参数的底层是一个数组,根据传递参数的个数不同会创建不同长度的数组来存储这些参数;传递的参数格式可以是0到多个
可变参数的使用示例:
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:
-
一个方法的参数列表只能用一个可变参数
-
如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
-
特殊写法,它可以接收任意数据类型的数据:
public static void method(Object... obj){ // 方法体 }
Python中同样有类似的机制:
- 当在方法的参数列表中声明类似于
*args的参数时,从此处开始直到结束的所有位置参数都将被收集到一个成为param的元组中 - 当在方法的参数列表中声明类似于
**args的参数时,从此处开始直到结束的所有位置参数都将被收集到一个成为param的字典中
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): 反转指定集合中元素的顺序 -
publicstaticvoidshuffle(List list): 将集合中的元素打乱 -
public static int frequency(Collection<?> c,Object o): 返回指定集合中指定元素的出现次数 -
public static void swap(List<?> list,int i,int j): 将指定集合中的 i 处元素和 j 处元素进行交换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方法。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] Collections.sort(list1); Collections.sort(list2); System.out.println(list1); // [1, 2, 3, 4, 5] System.out.println(list2); // [abc, bde, ccb] } }例如在String中实现了
Comparable<String>接口,并重写了compareTo方法: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>): 将集合中的元素按照指定的规则进行排序import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; public class CollectionsTest { public static void main(String[] args) { ArrayList<String> list2 = new ArrayList<>(); Collections.addAll(list2, "abc", "ccb", "bde"); System.out.println(list2); // [abc, ccb, bde] // 新建一个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] } }那么两种sort方法中的Comparable和Comparator有什么区别呢?
- Comparable:自己和传入的参数进行比较,使用时需要实现
Comparable<String>接口,并重写compareTo方法,它相当于一个内部的排序器 - Comparator:自定义的排序规则来比较两个对象,它相当于一个外部的排序器
- Comparable:自己和传入的参数进行比较,使用时需要实现
-
public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key): 在集合中查找某个元素的下标,但集合的元素必须是T或T的子类对象,而且必须是可比较大小的,即支持自然排序的。而且集合也事先必须是有序的,否则结果不确定 -
public static <T> int binarySearch(List<? extends T> list,T key,Comparator<? super T> c): 在集合中查找某个元素的下标,但集合的元素必须是T或T的子类对象,而且集合也事先必须是按照c比较器规则进行排序过的,否则结果不确定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 是一个包装类。它包含有各种有关集合操作的静态多态方法,此类不能实例化,通过类名直接使用其中的方法