排序——升序降序的使用

96
奔跑的佩恩
2017.12.26 10:46* 字数 696

前言

在做项目的过程中,偶尔会用到对集合中数据进行升序降序的排列问题,问题不是很难,但有时处理起来非常浪费时间,于是今天就把排序问题稍微处理了下,整理成一个排序工具类——CompareSortor

本文参考以下链接
Comparable、Comparator区别、Comparator升序降序实现
Collections 实现List简单升序降序 以及 各种用法
在此表示感谢。

今天讲解的内容涉及到:

  • Comparator比较大小的原理
  • list排序方法
  • CompareSortor使用的讲解

下面就来讲讲它的使用

一.Comparator比较大小的原理

先看一段代码:

                List<Integer> list = new ArrayList<>();
                list.add(1);
                list.add(9);
                list.add(3);
                list.add(7);
                Collections.sort(list, new Comparator<Integer>() {
                    @Override
                    public int compare(Integer t1, Integer t2) {
                        int i=0;
                        int compare=t1-t2;
                        if(compare>0){
                            i=1;
                        }else if(compare<0){
                            i=-1;
                        }
                        return i;
                    }
                });
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果:

E/pei: MainActivity:======list===[1, 3, 7, 9]

以上是做一个list<Integer>集合的升序排列,用到Collections.sort(... , ....)方法,然后要实现Comparator接口,重写Comparator类中compare(Integer t1, Integer t2)方法,当按升序排列的时候,t1-t2>0返回1,t1-t2=0返回0,t1-t2<0返回-1

二.list排序方法
2.1Collections.sort(list),默认升序排列

代码如下:

 List<Integer> list = new ArrayList<>();
                list.add(1);
                list.add(9);
                list.add(3);
                list.add(7);
                Collections.sort(list);
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果

E/pei: MainActivity:======list===[1, 3, 7, 9]
2.3Collections.sort(list),字母顺序排序

代码如下:

          List<String> list = new ArrayList<>();
                list.add("a");
                list.add("c");
                list.add("d");
                list.add("b");
                Collections.sort(list);
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果

E/pei: MainActivity:======list===[a, b, c, d]
2.4Collections.sort(list),按汉字拼音升序排列

代码如下:

List<String> list = new ArrayList<>();
                list.add("我");
                list.add("和");
                list.add("你");
                list.add("他");
                Collections.sort(list, Collator.getInstance(java.util.Locale.CHINA));
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果:

MainActivity:======list===[和, 你, 他, 我]
2.5Collections.reverse(list),逆向排序

将汉字数组按z-a的顺序排列:

                List<String> list = new ArrayList<>();
                list.add("我");
                list.add("和");
                list.add("你");
                list.add("他");
                Collections.sort(list, Collator.getInstance(java.util.Locale.CHINA));
                Collections.reverse(list);//反转整个数组
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果:

E/pei: MainActivity:======list===[我, 他, 你, 和]
2.5Collections.reverse(list),数字降序

代码如下:

                List<Double> list = new ArrayList<>();
                list.add(5.7d);
                list.add(5.72d);
                list.add(6.33d);
                list.add(15.2d);
                Collections.sort(list);
                Collections.reverse(list);//反转整个数组
                LogUtil.e(MainActivity.class,"======list==="+list.toString());

打印结果

E/pei: MainActivity:======list===[15.2, 6.33, 5.72, 5.7]
2.6Collections.shuffle(list),随机排序
                List<Double> list = new ArrayList<>();
                list.add(5.7d);
                list.add(5.72d);
                list.add(6.33d);
                list.add(15.2d);
                Collections.shuffle(list);//随机排序
                LogUtil.e(MainActivity.class,"===1===list==="+list.toString());
                Collections.shuffle(list);//随机排序
                LogUtil.e(MainActivity.class,"===2===list==="+list.toString());

打印结果:

MainActivity:===1===list===[5.72, 6.33, 15.2, 5.7]
MainActivity:===2===list===[5.72, 15.2, 6.33, 5.7]
2.7Collections.rotate(List<T>list,int i);,循环移动

i大于0时表示向右移动,i小于0时表示向左移动
代码如下:

                List<String> list = Arrays.asList("大学","高中","初中","小学","幼儿园");
                Collections.rotate(list,1);//右移一位
                LogUtil.e(MainActivity.class,"===1===list==="+list.toString());
                List<String> list2 = Arrays.asList("大学","高中","初中","小学","幼儿园");
                Collections.rotate(list2,-2);//左移两位
                LogUtil.e(MainActivity.class,"===2===list==="+list2.toString());

打印结果:

MainActivity:===1===list===[幼儿园, 大学, 高中, 初中, 小学]
MainActivity:===2===list===[初中, 小学, 幼儿园, 大学, 高中]
2.8Collections.swap(List<T>list,int a,int b);,元素换位

a,b表示要相互换位的元素下标
代码如下:

List<String> list = Arrays.asList("大学","高中","初中","小学","幼儿园");
                Collections.swap(list,0,3);//
                LogUtil.e(MainActivity.class,"===1===list==="+list.toString());

打印结果:

MainActivity:===1===list===[小学, 高中, 初中, 大学, 幼儿园]
三.CompareSortor使用的讲解
3.1先给出一个对象model类Student

代码如下:

package com.android.model;

/**
 * Title:
 * Description:
 * <p>
 * Created by pei
 * Date: 2017/12/22
 */
public class Student extends BaseModel{

    private String name;
    private int age;

    public Student(){}

    public Student(String name,int age){
        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;
    }

}

3.2 然后是排序工具类CompareSortor

代码如下:

package com.android.ui;

import com.android.util.CollectionUtil;
import com.android.util.StringUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * Title:排列工具类
 * Description:
 * <p>
 * Created by pei
 * Date: 2017/12/22
 */
public class CompareSortor<T> implements Comparator<T> {

    private String mFieldName;
    private boolean mReverse;//是否为降序排列,默认false

    private CompareSortor() {}

    private static class Holder {
        private static CompareSortor instance = new CompareSortor();
    }

    public static CompareSortor getInstance(){
        return CompareSortor.Holder.instance;
    }

    /**升序排列数值集合**/
    public List<T>sortList(List<T>list) {
        mReverse=false;
        return getFieldList(list);
    }

    /**升序排列对象集合**/
    public List<T>sortList(List<T>list,String fieldName){
        mReverse=false;
        return getObjectList(list,fieldName);
    }

    /**降序排列数值集合**/
    public List<T>reverseList(List<T>list){
        mReverse=true;
        return getFieldList(list);
    }

    /**降序排列对象集合**/
    public List<T>reverseList(List<T>list,String fieldName){
        mReverse=true;
        return getObjectList(list,fieldName);
    }

    /**自定义排列规则**/
    public List<T>customList(List<T>list,Comparator<T>comparator){
        if(CollectionUtil.isNotEmpty(list)){
            Collections.sort(list, comparator);
            return list;
        }
        List<T>newList=new ArrayList<>();
        return newList;
    }

    @Override
    public int compare(Object t1, Object t2) {
        if (t1 instanceof Integer) {//int
            return mReverse ? reverseCompare((int) t1, (int) t2) : sortCompare((int) t1, (int) t2);
        } else if (t1 instanceof Float) {//float
            return mReverse ? reverseCompare((float) t1, (float) t2) : sortCompare((float) t1, (float) t2);
        } else if (t1 instanceof Double) {//double
            return mReverse ? reverseCompare((double) t1, (double) t2) : sortCompare((double) t1, (double) t2);
        } else if (t1 instanceof Long) {//long
            return mReverse ? reverseCompare((long) t1, (long) t2) : sortCompare((long) t1, (long) t2);
        } else if (t1 != null && t2 != null) {//object
            Object obj1 = getFieldValueByName(mFieldName, t1);
            Object obj2 = getFieldValueByName(mFieldName, t2);
            return compare(obj1, obj2);
        } else {
            String classCastException = "强转异常:" + mFieldName + "不能转化成int,float,double,long中的任何一种类型";
            throw new ClassCastException(classCastException);
        }
    }

    /**int升序**/
    private int sortCompare(int t1,int t2){
        int i=0;
        int compare=t1-t2;
        if(compare>0){
            i=1;
        }else if(compare<0){
            i=-1;
        }
        return i;
    }

    /**float升序**/
    private int sortCompare(float t1,float t2){
        int i=0;
        float compare=t1-t2;
        if(compare>0){
            i=1;
        }else if(compare<0){
            i=-1;
        }
        return i;
    }

    /**double升序**/
    private int sortCompare(double t1,double t2){
        int i=0;
        double compare=t1-t2;
        if(compare>0){
            i=1;
        }else if(compare<0){
            i=-1;
        }
        return i;
    }

    /**long升序**/
    private int sortCompare(long t1,long t2){
        int i=0;
        long compare=t1-t2;
        if(compare>0){
            i=1;
        }else if(compare<0){
            i=-1;
        }
        return i;
    }

    /**int降序**/
    private int reverseCompare(int t1,int t2){
        int i=0;
        int compare=t1-t2;
        if(compare>0){
            i=-1;
        }else if(compare<0){
            i=1;
        }
        return i;
    }

    /**float降序**/
    private int reverseCompare(float t1,float t2){
        int i=0;
        float compare=t1-t2;
        if(compare>0){
            i=-1;
        }else if(compare<0){
            i=1;
        }
        return i;
    }

    /**double降序**/
    private int reverseCompare(double t1,double t2){
        int i=0;
        double compare=t1-t2;
        if(compare>0){
            i=-1;
        }else if(compare<0){
            i=1;
        }
        return i;
    }

    /**long降序**/
    private int reverseCompare(long t1,long t2){
        int i=0;
        long compare=t1-t2;
        if(compare>0){
            i=-1;
        }else if(compare<0){
            i=1;
        }
        return i;
    }

    /**
     * 根据属性名获取属性值 
     */
    private Object getFieldValueByName(String fieldName,Object obj) {
        Object value = null;
        if (obj != null) {
            try {
                String firstLetter = fieldName.substring(0, 1).toUpperCase();
                String getter = "get" + firstLetter + fieldName.substring(1);
                Method method = obj.getClass().getMethod(getter, new Class[]{});
                value = method.invoke(obj, new Object[]{});
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
        return value;
    }

    /**排列数值集合**/
    private List<T>getFieldList(List<T>list) {
        List<T> newlist = new ArrayList<>();
        this.mFieldName=null;
        if (CollectionUtil.isNotEmpty(list)) {
            Collections.sort(list, CompareSortor.this);
            for (T t : list) {
                newlist.add(t);
            }
        }
        return newlist;
    }

    /**排列对象集合**/
    private List<T>getObjectList(List<T>list,String fieldName){
        if(StringUtil.isNotEmpty(fieldName)){
            List<T>newlist=new ArrayList<>();
            if(CollectionUtil.isNotEmpty(list)){
                this.mFieldName=fieldName;
                Collections.sort(list,CompareSortor.this);
                for(T t:list){
                    newlist.add(t);
                }
            }
            return newlist;
        }else{
            String nullPointerException="空指针:调用getArraysList(List<T>list,String fieldName)方法时对象属性名称fieldName不能为空";
            throw new NullPointerException(nullPointerException);
        }
    }
}
3.3 CompareSortor对数字排序

代码如下:

                List<Integer>listk=new ArrayList<>();
                listk.add(1);
                listk.add(9);
                listk.add(3);
                listk.add(7);
                List<Integer>fList=CompareSortor.getInstance().sortList(listk);
                LogUtil.e(MainActivity.class,"=====fList====="+fList.toString());

打印结果:

 MainActivity:=====fList=====[1, 3, 7, 9]
3.4 CompareSortor对对像按其属性中数字大小排序

下面是对Student以age排序(注:age需要是数字,即int,float,double,long类型)

                Student stu1=new Student("c",12);
                Student stu2=new Student("a",17);
                Student stu3=new Student("d",10);
                Student stu4=new Student("b",15);

                List<Student>list=new ArrayList<>();
                list.add(stu1);
                list.add(stu2);
                list.add(stu3);
                list.add(stu4);

//                List<Student>studentList=CompareSortor.getInstance().sortList(list,"age");
                List<Student>studentList=CompareSortor.getInstance().reverseList(list,"age");
                for(Student s:studentList){
                    LogUtil.e(MainActivity.class,"=========s="+s.toString());
                }

打印结果:

MainActivity:=========s=age=17  name=a 
MainActivity:=========s=age=15  name=b 
MainActivity:=========s=age=12  name=c
MainActivity:=========s=age=10  name=d  

CompareSortor.getInstance().sortList(list,"age");方法中list表示要排序的集合,age表示list中对象是以age属性进行排列的。

当然,仅这些远远不足以满足我们的开发需求,于是有一个自定义比较方法

3.5 CompareSortor自定义排序方法
               List<Student>studentList=CompareSortor.getInstance().customList(list, new Comparator() {
                    @Override
                    public int compare(Object obj1, Object obj2) {
                        //写自己的排序规则
                        //...
                        return 0;
                    }
                });

OK,今天关于排序的就讲到这里了,谢谢诶大家

算法
Web note ad 1