第一类:自己封装排序框架;
1.首先定义一个SortUtil的类,在里面写一个sort的静态方法;
public class SortUtil {
public static void sort(ArrayList<User> userList,Bijiao bijiao){
//需要有一个比较器,告诉我i与i+1的大小比较结果,创建一个比较的接口,写一个方法,返回布尔值,参数是两个user对象
for(int j=0;j<userList.size()-1;j++){
for(int i=0;i<userList.size()-1-j;i++){
boolean bool = bijiao.bi(userList.get(i), userList.get(i+1));
if(bool){
User tep = userList.get(i);
userList.set(i,userList.get(i+1));
userList.set(i+1, tep);
}
}
}
}
}
如果把比较的属性定死了,那么这个方法实用性就太差了,所以不能把要比较的属性定死;那么就需要有一个方法,通过传入userList.get(i)和userList.get(i+1)就能比较他们并且返回一个boolean值;然后再根据这个布尔值进行判断和排序;
但是这个方法还未实现,所以用定义一个bijiao的接口;
public interface Bijiao {
public boolean bi(User u1,User u2);
}
这个接口规定了在实现类中一定要有一个方法传入两个user对象时能返回一个布尔值;
然后就可以依照具体的排序方式定义具体的实现类了,例如:
public class ageCompare implements Bijiao {
@Override
public boolean bi(User u1, User u2) {
if(u1.getAge()<u2.getAge()){
return true;
}
return false;
}
}
需要什么排序就定义什么样的实现类;(所以说一个接口可以有很多个实现类:同时,一个类也可以实现多个接口)
然后只要在测试方法中写:
SortUtil.sort(集合名,new ageCompare()即可);
参数中第一个是集合的名称,但这个集合中只能是 user对象,因为sort方法里已经规定死了;第二个参数就是new一个实现类;
2.第一种方法虽然已经实现了封装一个sort方法,但是他限定了sort方法中传入的一定要是一个user对象的集合,所以使用的局限性很大;
因此引入了泛型,我们可以维持同样的思路只是不规定集合中一定要是user对象;
修改如下:public interface Bijiao <T>{
public boolean bi(T u1,T u2);
}在接口中利用泛型,传入一个不知什么类型的参数,这样后面只要在调用的时候能确定这个类型是什么就可以了;
排序方法也要修改:
public class SortUtil {//此时sort不能是静态方法,因为这样写是作用于整个类的;
public void sort(ArrayList<D> list,Bijiao bijiao){
//需要有一个比较器,告诉我i与i+1的大小比较结果,创建一个比较的接口,写一个方法,返回布尔值,参数是两个user对象
for(int j=0;j<userList.size()-1;j++){
for(int i=0;i<userList.size()-1-j;i++){
boolean bool = bijiao.bi(list.get(i),list.get(i+1));
if(bool){
D tep = list.get(i);
list.set(i,list.get(i+1));
list.set(i+1, tep);
}
}
}
}
}
实现类也要进行修改,与接口保持一致:
//此时实现类中就不可以再用泛型了,因为实现类中要确定比较哪些属性,如果还用泛型,就无法确//定这个对象中到底具有哪些属性;
public class ageCompare implements Bijiao{
@Override
public boolean bi(User u1, User u2) {
if(u1.getAge()<u2.getAge()){
return true;
}
return false;
}
}
所以在测试方法中应该这样写:
SortUtil sortU = new SortUtil<>();
//因为此时sort已不再是静态方法,所以要先new一个;而这个时候传入的 就规定了用sortU调用sort方法时,集合中的对象一定要是User类型;
sortU.sort(userList, new ageCompare());
2.1
如果希望sort还能是静态方法,则要这样写:
public class SortUtil{
//将写在这个方法体上,表示只作用于这个方法体;
public static void sort(ArrayList list,Bijiao bijiao){
//需要有一个比较器,告诉我i与i+1的大小比较结果,创建一个比较的接口,写一个方法,返回布尔值,参数是两个user对象
for(int j=0;j<list.size()-1;j++){
for(int i=0;i<list.size()-1-j;i++){
boolean bool = bijiao.bi(list.get(i), list.get(i+1));
if(bool){
T tep = list.get(i);
list.set(i,list.get(i+1));
list.set(i+1, tep);
}
}
}
}
}
测试时这样写:
SortUtil.sort(userList, new ageCompare());
//由于传入的userList中的对象是user,所以后面的实现类中也只能是user
3.第二种方法用泛型扩大了使用范围,但是每比较一次不同的属性,就要创建一个实现类太过麻烦,可以写一个匿名内部类去实现接口;
测试时这样写:
//如果sort此时是静态方法:
SortUtil.sort(userList, new Bijiao(){
public boolean bi(User u1, User u2) {
if(u1.getAge()>u2.getAge()){
return true;
}
return false;
}
});
//实际上这种方法跟写了一个实现类的原理是一样的,只是没有单独新创建一个,而是在内部直接写而已;
第二类,用Collections工具排序:
4.实际实现原理与第三种一模一样;只是这个排序的封装类叫Collections,排序方法叫sort是一个静态方法,然后需要实现一个叫做Comparator的接口,这个接口中有一个方法叫compare是用来比较具体的属性的;
具体如下:Collections.sort(userList, new Comparator() {
public int compare(User u1,User u2){
if(u1.getAge()>u2.getAge()){
return 1;
}
return -1;
}
});
与第一类的第3个方法做类比:
Collections====SortUtil;
sort====sort;
Comparator====Bijiao;
public int compare(T u1,T u2)==public boolean bi(D u1,D u2);
Collections方法用的是快速排序,而我们用的是冒泡排序;compare方法返回值是int,如果是证书,则认为条件中比较是true,反之则是负数;如果二者相等,返回0;
5.依然是用Collections工具;但是这次利用的是User类中自带的compareTo方法;
实现思路是:
public class Collection {//此时sort不能是静态方法,因为这样写是作用于整个类的;
public static <D> void sort(ArrayList<D> list){
//需要有一个比较器,告诉我i与i+1的大小比较结果,创建一个比较的接口,写一个方法,返回布尔值,参数是两个user对象
for(int j=0;j<list.size()-1;j++){
for(int i=0;i<list.size()-1-j;i++){
//这种方法不需要比较的接口,只要D类本身带有一个compareTo方法即可实现比较;
if(list.get(i).compareTo(list.get(i+1)){
D tep = list.get(i);
list.set(i,list.get(i+1));
list.set(i+1, tep);
}
}
}
}
}
但是D类要实现这个方法,必须得是Comparable的实现类;
假设D是Product类,则需要这样写:
public class Product implements Comparable
即将Product类定义为Comparable的实现类,而这个实现类中必须要实现一个compare方法,去比较引用这个方法的对象的属性值与同是这个类对象的属性值,返回值与上同理:
public int compareTo(Product o) {
if(this.getProPrice()>o.getProPrice()){
return 1;
}
return -1;
}
测试中只要写:Collections.sort(userList);即可;
梳理一下:调用了Collections类中的静态sort方法,这个方法只需要传一个集合,有一个接口Comparable,里面需要实现一个compareTo方法,用来比较具体的属性值;所以让Product类成为这个接口的实现类,制定实现compareTo方法的规则,然后在做排序时只要对象引用自己本身类的compareTo方法即可;
这个方法的弊端是,compareTo方法只能有一个,所以只能做一种排序;
第四种方式是最佳的;