概述
Set 接口有实现类TreeSet
,Map 接口有实现类 TreeMap
实现集合的排序。
但 List 接口没有实现排序的类,所以提供类Collections
:是针对集合操作的工具类,都是静态方法,为 List 接口提供排序等一系列功能。
常用方法
- 排序
- public static <T extends Comparable<? super T>> void
sort
(List<T> list) :默认是自然排序。 - public static <T> void
sort
(List<T> list,Comparator<? super T> c
) : 比较器排序
- public static <T extends Comparable<? super T>> void
- 二分查找
- public static <T> int
binarySearch
(List<? extends Comparable<? super T>> list, T key) :默认是自然排序,排序后二分法查找。 - public static <T> int
binarySearch
(List<? extends T> list, T key,Comparator<? super T> c
) :比较器排序,排序后二分法查找。
- public static <T> int
- 最大值
- public static <T extends Object & Comparable<? super T>> T
max
(Collection<? extends T> coll) :默认是自然排序,排序后查找最大值。 - public static <T> T
max
(Collection<? extends T> coll,Comparator<? super T> comp
) :比较器排序,排序后查找最大值。
- public static <T extends Object & Comparable<? super T>> T
- 反转
- public static void
reverse
(List<?> list)
- public static void
- 随机置换
- public static void
shuffle
(List<?> list) - public static void
shuffle
(List<?> list, Random rnd)
- public static void
注:public static <T extends Comparable<? super T>> void sort(List<T> list) 表示该方法中传递的泛型参数必须实现了Comparable中的
compareTo(T o)
方法,否则进行不了sort排序。
自然排序
public class Student implements Comparable<Student> {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
// 先排序姓名,再排序年龄
public int compareTo(Student s) {
int num = this.name.compareTo(s.name);
int num2 = num == 0 ? this.age - s.age : num;
return num2;
}
}
public class CollectionsDemo {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();
list.add(new Student("lili",21));
list.add(new Student("lili",21));
list.add(new Student("lili",22));
list.add(new Student("jack",23));
list.add(new Student("alin",25));
System.out.println(list);
// 自然排序 先排序姓名,再排序年龄
Collections.sort(list);
System.out.println(list);
// 比较器排序 先排序年龄,再排序姓名
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge();
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
return num2;
}
});
System.out.println(list);
}
}
输出:
[Student{name='lili', age=21}, Student{name='lili', age=21}, Student{name='lili', age=22}, Student{name='jack', age=23}, Student{name='alin', age=25}]
[Student{name='alin', age=25}, Student{name='jack', age=23}, Student{name='lili', age=21}, Student{name='lili', age=21}, Student{name='lili', age=22}]
[Student{name='lili', age=21}, Student{name='lili', age=21}, Student{name='lili', age=22}, Student{name='jack', age=23}, Student{name='alin', age=25}]
结果看出,自然排序会调用 Student 定义的排序规则;而如果sort第二个参数集合实现自己的排序规则(比较器排序),会优先使用比较器排序规则。
其他方法
public class CollectionsDemo {
public static void main(String[] args) {
// 创建集合对象
List<Integer> list = new ArrayList<Integer>();
// 添加元素
list.add(30);
list.add(20);
list.add(50);
list.add(10);
list.add(40);
System.out.println("list:" + list);
Collections.sort(list);
System.out.println("list:" + list);
// public static <T> int binarySearch(List<?> list,T key):二分查找
System.out.println("binarySearch:" + Collections.binarySearch(list, 40));
System.out.println("binarySearch:" + Collections.binarySearch(list, 100));
// public static <T> T max(Collection<?> coll):最大值
System.out.println("max:"+Collections.max(list));
// public static void reverse(List<?> list):反转
Collections.reverse(list);
System.out.println("list:" + list);
//public static void shuffle(List<?> list):随机置换
Collections.shuffle(list);
System.out.println("list:" + list);
}
}
输出:
list:[30, 20, 50, 10, 40]
list:[10, 20, 30, 40, 50]
binarySearch:3
binarySearch:-6
max:50
list:[50, 40, 30, 20, 10]
list:[10, 20, 40, 50, 30]
注:调用二分查找方法
binarySearch()
前,需要先进行排序sort()
,不然调用binarySearch()
返回索引值不正确。
HashSet排序
对于列表,我们使用Collections.sort(List)方法。如果我们想要排序HashSet怎么办?
方案一:
将HashSet集合复制到List,然后对 List 进行排序。
Set<?> yourHashSet = new HashSet<>();
List<?> sortedList = new ArrayList<>(yourHashSet);
Collections.sort(sortedList);
方案二
将HashSet集合复制到TreeSet,您将获得一个有序集。
HashSet myHashSet = new HashSet();
myHashSet.add(1);
myHashSet.add(23);
myHashSet.add(45);
myHashSet.add(12);
TreeSet myTreeSet = new TreeSet(myHashSet);
/*TreeSet myTreeSet = new TreeSet();
myTreeSet.addAll(myHashSet);*/
System.out.println(myTreeSet); // Prints [1, 12, 23, 45]
注:有两种方法将HashSet赋值给TreeSet。
- 一种是:构造方法
TreeSet myTreeSet = new TreeSet(myHashSet);
- 另一种:
addAll()
方法,myTreeSet.addAll(myHashSet)。
引申
可以通过stream()流操作 list 集合。
Stream流 - 获取Stream和转换操作