Collections

java.utils.Collections 是集合工具类,用来对集合进行操作。Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。

常用方法:

  • public static <T> boolean addAll(Collection<T> c, T...elements): 将所有指定元素添加到指定 collection 中

参数列表中的T...elements表示可变参数,当方法的参数数据类型已经确定,但参数的个数不确定就可以使用可变参数。

  • 格式:定义方法时使用
    1. 修饰符 返回值类型 方法名(数据类型... 变量名){
    2. // 方法体
    3. }
  • 原理:可变参数的底层是一个数组,根据传递参数的个数不同会创建不同长度的数组来存储这些参数;传递的参数格式可以是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 list1 = new ArrayList<>(); ArrayList 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]
}

}


<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 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]
}

}


<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 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化