对象列表按照某字段进行排序

时间:2022-05-24 20:25:22

>运用JDK中提供的比较器

package test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * 主要类
 * @author hyson
 *
 */
public class Test2 {
    public static void main(String[] args) {
        //新建对象列表
        List<Man> list = new ArrayList<Man>();
        for (int i = 10; i > 0; i--) {
            list.add(new Man(i, "a" + i));
        }
        //转换成数组
        Man[] ms = list.toArray(new Man[list.size()]);

        for (Man person : ms) {
            System.out.println("姓名:" + person.getName() + "  年龄:" + (10 + person.getAge()) + "     ");
        }
        System.out.println();

        //对象按年龄排序
        Arrays.sort(ms, new CompareManAge());
        
        //对象不转数组直接按年龄排序
        //Collections.sort(list,new CompareManAge());

        for (Man person : ms) {
            System.out.println("姓名:" + person.getName() + "  年龄:" + (10 + person.getAge()) + "     ");
        }
        System.out.println();

    }
}

/**
 * 实现比较器,对年龄进行比较
 * 
 * @author hyson
 * 
 */
class CompareManAge implements Comparator<Man> {

    public int compare(Man m1, Man m2) {
        int temp = 0;
        if (m1.getAge() > m2.getAge()) {
            temp = 1;
        } else if (m1.getAge() == m2.getAge()) {
            temp = 0;
        } else {
            temp = -1;
        }
        return temp;
    }

}

/**
 * 要排序的对象
 * 
 * @author hyson
 * 
 */
class Man {
    private int age;
    private String name;

    public Man(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

>分析比较器

    实现原理:

实现比较器接口,排序方法中调用该接口的实现来判定相应字段大小;

Collections类与Arrays类实现了依据比较器接口判定大小的实现排序;

        完成对于对象列表排序。

我这里重新定义了下比较器接口,实现如下:

package test;

import java.util.ArrayList;
import java.util.List;

public class Test3 {

    /**
     * @param args
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void main(String[] args) {
        List<People> list = new ArrayList<People>();
        for (int i = 10; i > 0; i--) {
            list.add(new People(i, "a" + i));
        }

        People[] ms = list.toArray(new People[list.size()]);

        for (People person : ms) {
            System.out.println("姓名:" + person.getName() + "  年龄:" + (10 + person.getAge()) + "     ");
        }
        System.out.println();

        ClazzSort.sort(ms, new Comp());

        for (People person : ms) {
            System.out.println("姓名:" + person.getName() + "  年龄:" + (10 + person.getAge()) + "     ");
        }
        System.out.println();
    }

}

/**
 * 排序类
 * 
 * @author hyson
 * 
 */
class ClazzSort {
    /**
     * 提供的排序方法
     * 
     * @param array 数组
     * @param c 比较器
     */
    public static <T> void sort(T[] array, Comp<? super T> c) {
        Object[] out = new Object[array.length];
        System.arraycopy(array, 0, out, 0, array.length);
        mergeSort(out, array, 0, array.length, c);
    }

    /**
     * Finds the place of specified range of specified sorted array, where the
     * element should be inserted for getting sorted array. Uses exponential
     * search algorithm.
     * 
     * @param arr - the array with already sorted range
     * @param val - object to be inserted
     * @param l - the start index
     * @param r - the end index
     * @param bnd - possible values 0,-1. "-1" - val is located at index more
     *            then elements equals to val. "0" - val is located at index
     *            less then elements equals to val.
     * @param c - the comparator used to compare Objects
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static int find(Object[] arr, Object val, int bnd, int l, int r, Comp c) {
        int m = l;
        int d = 1;
        while (m <= r) {
            if (c.compare(val, arr[m]) > bnd) {
                l = m + 1;
            } else {
                r = m - 1;
                break;
            }
            m += d;
            d <<= 1;
        }
        while (l <= r) {
            m = (l + r) >>> 1;
            if (c.compare(val, arr[m]) > bnd) {
                l = m + 1;
            } else {
                r = m - 1;
            }
        }
        return l - 1;
    }

    /**
     * 优化的快速排序
     * 
     * @param in 传入数组
     * @param out 传出数组
     * @param start 起始位置
     * @param end 结束位置
     * @param c 比较器
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static void mergeSort(Object[] in, Object[] out, int start, int end, Comp c) {
        //排序数组长度
        int len = end - start;
        //小于7,运用快速快速排序
        if (len <= 7) {
            for (int i = start + 1; i < end; i++) {
                Object current = out[i];
                Object prev = out[i - 1];
                //实现比较器类的方法进行比较
                if (c.compare(prev, current) > 0) {
                    int j = i;
                    do {
                        out[j--] = prev;
                    } while (j > start && (c.compare(prev = out[j - 1], current) > 0));
                    out[j] = current;
                }
            }
            return;
        }

        //快速排序
        int med = (end + start) >>> 1;
        mergeSort(out, in, start, med, c);
        mergeSort(out, in, med, end, c);

        // 合并

        // 如果有序不合并返回
        if (c.compare(in[med - 1], in[med]) <= 0) {
            System.arraycopy(in, start, out, start, len);
            return;
        }
        int r = med, i = start;

        // use merging with exponential search
        do {
            Object fromVal = in[start];
            Object rVal = in[r];
            if (c.compare(fromVal, rVal) <= 0) {
                int l_1 = find(in, rVal, -1, start + 1, med - 1, c);
                int toCopy = l_1 - start + 1;
                System.arraycopy(in, start, out, i, toCopy);
                i += toCopy;
                out[i++] = rVal;
                r++;
                start = l_1 + 1;
            } else {
                int r_1 = find(in, fromVal, 0, r + 1, end - 1, c);
                int toCopy = r_1 - r + 1;
                System.arraycopy(in, r, out, i, toCopy);
                i += toCopy;
                out[i++] = fromVal;
                start++;
                r = r_1 + 1;
            }
        } while ((end - r) > 0 && (med - start) > 0);

        // 复制剩余数组
        if ((end - r) <= 0) {
            System.arraycopy(in, start, out, i, med - start);
        } else {
            System.arraycopy(in, r, out, i, end - r);
        }

    }
}

/**
 * 比较器
 * 
 * @author hyson
 * 
 * @param <T>任意类
 */
interface Com<T> {
    int compare(T o1, T o2);
}

/**
 * 实现比较器
 * 
 * @author hyson
 * 
 * @param <T>
 */
class Comp<T> implements Com<People> {

    public int compare(People m1, People m2) {
        int temp = 0;
        if (m1.getAge() > m2.getAge()) {
            temp = 1;
        } else if (m1.getAge() == m2.getAge()) {
            temp = 0;
        } else {
            temp = -1;
        }
        return temp;
    }

}

/**
 * 待排序对象
 * 
 * @author hyson
 * 
 */
class People {
    private int age;
    private String name;

    public People(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}