目录
Collections类
常用成员方法:
比较器的使用:
源码分析:
Collection和Collections区别:
Collection: 是单列集合的根接口
Collections: 集合的工具类
集合转数组:集合对象.toArray() -------------返回一个Object[ ]
数组转集合: Arrays.asList(T...t) ----------- 得到的集合不能add ,remove,需要 new ArrayList<>(Arrays.asList(T...t))
public static
public static
public static
public static void reverse(List> list) -------------- 集合的逆序
public static void shuffle(List> list) -------------- 打乱集合的排序
public static
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class CollectionDemo01 {
public static void main(String[] args) {
List list = Arrays.asList(12,3,6,5,9,4,5,60);
Collections.sort(list);//默认是升序的
System.out.println(list); //[3, 4, 5, 5, 6, 9, 12, 60]
System.out.println(Collections.binarySearch(list, 4)); //1
System.out.println(Collections.max(list)); //60 --- 参数为Collection类型的,因此也可以是Set
Collections.reverse(list); //反转
System.out.println(list); //[60, 12, 9, 6, 5, 5, 4, 3]
System.out.println(Collections.binarySearch(list, 4)); //-1 ,Collection的二分查找与list一致,只适合升序
Collections.shuffle(list); //随机大乱(斗地主发牌)
System.out.println(list); //[3, 5, 9, 6, 12, 60, 4, 5]
/**
* Collection怎么对对象排序
* 该对象所在的类必须实现Comparable接口
*/
}
通过Collections.sort()方法已经可以对一些集合实现排序的功能,如果想对List
Comparable:内部比较器,java.lang; 如果一个List想要使用Collections.sort() 做排序,需要集合中的元素所在的类实现Comparable
接口,重写compareTo: this在前:升序; 参数在前:降序
Comparator:外部比较器,java.util; 如果一个类中不能实现Comparable,或者是对应Comparable中的排序方式不满意,可以通过Comparator重新定义排序的规则,而不需要修改原有类的结构。Collections.sort(list,Comparator) //匿名内部类;
与Comparable接口相比,Comparator不需要修改类的结构,更加灵活。
内部比较器Comparable接口:
public class Person implements Comparable{
String name;
int age;
double score;
public Person() {
super();
}
public Person(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", score=" + score + "]";
}
//需求:默认使用年龄的升序,如果年龄相同,按照分数的降序
@Override
public int compareTo(Person o) { //int类型不可更改
//Person p = (person)o;
if(this.age == o.age) {
//return (int)(o.score - this.score); --- 强制类型转换的会使得相近的double类型的数字的差变为0
return (o.score>this.score)?-1:(o.score==this.score)?0:1;
}
return (this.age - o.age);
}
}
注:集合List
public class SortDemo {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(new Person("Jerry",19));
list.add(new Person("Tom",15));
list.add(new Person("Jack",39));
list.add(new Person("Rose",29));
/* for(int i=0;i
外部比较器Comparator接口:
注:有的类已经实现了Comparable接口,此时如果希望修改实现方式只能继承后重写compareTo方法,但并不是所有的类都能继承,比如Integer类中实现了Comparable接口,默认使用升序,此时想要继承Integer类重写compareTo方法则不可能,因为他是用final修饰的。
public class ComparatorDemo01 {
public static void main(String[] args) {
//Integer中默认升序,如果要实现降序
List list = Arrays.asList(1,2,5,6,3,8,9);
Collections.sort(list);
System.out.println(list); //[1, 2, 3, 5, 6, 8, 9]
/**
* public static void sort(List list, Comparator super T> c)
* public interface Comparator {
* int compare(T o1, T o2);
* }
*/
//改写方式一:
Collections.sort(list,new IntegerComparator());
System.out.println(list); //[9, 8, 6, 5, 3, 2, 1]
Collections.shuffle(list); //打乱顺序
//改写方式二:使用匿名内部类
Collections.sort(list, new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(list);
}
}
//这种方式不建议,很繁琐。
class IntegerComparator implements Comparator{
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
}
public static
我们在使用外部比较器Comparator时进行排序时,会重写compare(T o1,T o2)方法。o1,o2是集合中相邻位置的元素。通过改变相邻位置元素o1与o2的位置我们会得到降序或升序的List集合。那具体底层是怎么设定的呢?我们来看一下:
Collections工具类中的sort()方法
======================================================================
public static void sort(List list, Comparator super T> c) {
list.sort(c);
}
List接口中的sort方法
================================================================
default void sort(Comparator super E> c) {
Object[] a = this.toArray();
Arrays.sort(a, (Comparator) c);
ListIterator i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
位于Arrays.class中
====================================================================
public static void sort(T[] a, Comparator super T> c) {
if (c == null) {
sort(a);
} else {
if (LegacyMergeSort.userRequested)
legacyMergeSort(a, c);
else
TimSort.sort(a, 0, a.length, c, null, 0, 0);
}
}
private static void legacyMergeSort(T[] a, Comparator super T> c) {
T[] aux = a.clone();
if (c==null)
mergeSort(aux, a, 0, a.length, 0);
else
mergeSort(aux, a, 0, a.length, 0, c);
}
private static void mergeSort(Object[] src,
Object[] dest,
int low,
int high,
int off) {
int length = high - low;
// Insertion sort on smallest arrays
if (length < INSERTIONSORT_THRESHOLD) {
for (int i=low; ilow && ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
swap(dest, j, j-1);
return;
}
...
}
由上可知:方法最终会调用到 mergeSort 方法上。当相邻元素o1,o2满足 dest[j-1]).compareTo(dest[j])>0,会调用swap操作,实现位置的互换。
当compare方法中的:
return o1-o2;
返回值为负数表示第一个参数比较小;
返回值为正数表示第一个参数比较大,调用swap方法。 --- 形成了所谓的默认升序
return o2-o1;
返回值为负数表示第二个参数比较小;
返回值为正数表示第二个参数比较大,调用swap方法。 --- 形成了所谓的自定义降序