该记录内容全是放在list里面排序的
Collections 类中的排序方法默认为升序即
- 如果定义A大于B返回1,则Collections.sort();为升序
- 如果定义A大于B返回-1,Collections.sort();为降序
通过sort排序的两种方法
- 元素类实现java.lang.Comparable接口,通过重写接口中的compareTo方法提供排序准则
- 提供一个业务排序类实现java.util.Comparator接口,重写compare方法提供排序准则。此方法解耦,独立于实体类,方便应对与各种排序规则。(而且在只提供字节码而没有提供源码可以修改的情况下只能选择这种方法,推荐使用!)
Comparable接口使用
- 很多内置类都实现了Comparable接口,可直接排序
如Integer(根据基本类型的数据大小返回-1,0,1)、Character(返回x-y,根据Unicode编码)、String(字符不等返回第一个不等的字符之差,如果相等则返回长度之差)、Date(返回日期的长整型之差)这些都调用sort方法升序的
内置类排序示例
- 自定义Person类,省略set/get方法
public class Person implements Comparable<Person>{
private String name;
private int handsome; //帅气度
public Person() {
}
public Person(String name, int handsome) {
this.name = name;
this.handsome = handsome;
}
//按帅气度降序排列
public int compareTo(Person o) {
return -(this.handsome-o.handsome);//默认升序,加个减号就可以了
}
//重写toString方法,便于查看输出
public String toString() {
return "姓名:"+name+",帅气度:"+handsome+"\n";
}
- 排序
public class Demo1 {
public static void main(String[] args) {
List<Person> list=new ArrayList<>();
list.add(new Person("张学友",105));
list.add(new Person("刘德华", 100));
list.add(new Person("Viking",300));
Collections.sort(list);
System.out.println(list);
}
}
Comparator接口实现自定义类排序
同样使用上面的Person类,但是由于Comparator接口是独立于实体类的,所以Person类无需实现什么东西,可保持其独立性;
- Person类
public class Person {
private String name;
private int handsome; //帅气度
public Person() {
}
public Person(String name, int handsome) {
this.name = name;
this.handsome = handsome;
}
//重写toString方法,便于查看输出
public String toString() {
return "姓名:"+name+",帅气度:"+handsome+"\n";
}
- 提供业务排序类,这里还是按照帅气度进行降序排序,简单重写Comparator接口中的compare方法即可
public class PersonHandsomSort implements Comparator<Person>{
//按降序,同样加个负号
public int compare(Person o1, Person o2) {
return -(o1.getHandsome()-o2.getHandsome());
}
}
- 排序
public class Demo1 {
public static void main(String[] args) {
List<Person> list=new ArrayList<>();
list.add(new Person("张学友",105));
list.add(new Person("刘德华", 100));
list.add(new Person("Viking",300));
Collections.sort(list, new PersonHandsomSort());
System.out.println(list);
}
Collections常用方法
-
二分法查找 binarySearch:
视频里说容器必须有序,但是经过实验似乎不需要有序API源码也可以处理,估计底层已经自动排序了。但不会更改原容器的顺序,返回也是正确的位置。
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)
这里的第一个通配符的意思是实现了Comparable接口的实体类元素,第二个通配符是指这个Comparable<>尖括号里头是实体类的父类或自身。
-
反转 reverse
void reverse(List<?> list)
没什么好说的 -
打乱顺序 shuffle
void shuffle()
以下给出应用,洗牌的程序。
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Integer> cards=new ArrayList<>();
//把牌装进数组里面
for(int i=1;i<55;i++){
cards.add(i); //这里自动装箱了!
}
//打乱顺序
Collections.shuffle(cards);
List<Integer> p1=new ArrayList<>();
List<Integer> p2=new ArrayList<>();
List<Integer> p3=new ArrayList<>();
List<Integer> last=new ArrayList<>();
//把牌发出去,因为已经打乱了顺序,从1开始一个一个发就好了
for(int i=0;i<cards.size();i+=3){
p1.add(cards.get(i));
p2.add(cards.get(i+1));
p3.add(cards.get(i+2));
}
//加底牌
last.add(cards.get(51));
last.add(cards.get(52));
last.add(cards.get(53));
//打印
System.out.println(p1);
System.out.println(p2);
System.out.println(p3);
System.out.println(last);
}
- 排序 sort
void sort(List<T> list);
void sort(List<T> list , Comparator<? super T> c);
前面已经讲到了,这里list内的元素,必须用上面两个方法之一定义过排序规则了才能使用这种排序。
-
交换元素 swap
void swap(List<?> list , int i , int j);