All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.apexes.commons.lang.Comparators Maven / Gradle / Ivy

There is a newer version: 2.1.6
Show newest version
/*
 * Copyright (c) 2018, apexes.net. All rights reserved.
 *
 *         http://www.apexes.net
 *
 */
package net.apexes.commons.lang;

import java.util.*;

/**
 * @author HeDYn
 */
public class Comparators {

    /**
     * 比较 version1 和 version2,如果 version1 小于、等于、大于 version2 分别返回 -1、0、1
     * @param version1 版本号1
     * @param version2 版本号2
     * @return 如果 version1 小于、等于、大于 version2 分别返回 -1、0、1
     */
    public static int versionCompare(String version1, String version2) {
        if (version1 == null) {
            if (version2 == null) {
                return 0;
            } else {
                return -1;
            }
        } else if (version2 == null) {
            return 1;
        }
        StringTokenizer t1 = new StringTokenizer(version1, "._");
        StringTokenizer t2 = new StringTokenizer(version2, "._");
        while (t1.hasMoreTokens()) {
            if (!t2.hasMoreTokens()) {
                return 1;
            }
            int n1 = Integer.parseInt(t1.nextToken());
            int n2 = Integer.parseInt(t2.nextToken());
            int d = n1 - n2;
            if (d != 0) {
                return d;
            }
        }
        return t2.hasMoreTokens() ? -1 : 0;
    }

    /**
     * 添加参与对比的属性
     * @param getter 获取属性值的方法
     * @param comparator 用于给属性做对比
     * @return 返回 {@link ComparatorHelper} 对象
     */
    public static  ComparatorHelper orderBy(ObjectGetter getter, Comparator comparator) {
        return new ComparatorHelper().orderBy(getter, comparator);
    }

    /**
     * 参与对比的属性
     * @param getter 获取要排序的属性值的方法
     * @return 返回 {@link ComparatorHelper} 对象
     */
    public static  ComparatorHelper orderBy(Getter getter) {
        return new ComparatorHelper().orderBy(getter);
    }

    /**
     * 参与对比的属性
     * @param getter 获取要排序的属性值的方法
     * @param asc 为true使用升序,为false使用降序
     * @return 返回 {@link ComparatorHelper} 对象
     */
    public static  ComparatorHelper orderBy(Getter getter, boolean asc) {
        return new ComparatorHelper().orderBy(getter, asc);
    }

    /**
     * 参与对比的属性
     * @param getter 获取要排序的属性值的方法
     * @return 返回 {@link ComparatorHelper} 对象
     */
    public static  ComparatorHelper ascBy(Getter getter) {
        return orderBy(getter, true);
    }

    /**
     * 参与对比的属性
     * @param getter 获取要排序的属性值的方法
     * @return 返回 {@link ComparatorHelper} 对象
     */
    public static  ComparatorHelper descBy(Getter getter) {
        return orderBy(getter, false);
    }

    /**
     * 对列表进行升序排序,为null的排在前面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void sort(List list, Getter getter) {
        orderBy(getter).sort(list);
    }

    /**
     * 对列表进行排序,为null的排在前面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     * @param asc 为true使用升序,为false使用降序
     */
    public static  void sort(List list, Getter getter, boolean asc) {
        orderBy(getter, asc).sort(list);
    }

    /**
     * 对列表进行排序,为null排在后面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void sortNullLast(List list, Getter getter) {
        orderBy(getter).nullLast().sort(list);
    }

    /**
     * 对列表进行排序,为null排在后面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     * @param asc 为true使用升序,为false使用降序
     */
    public static  void sortNullLast(List list, Getter getter, boolean asc) {
        orderBy(getter, asc).nullLast().sort(list);
    }

    /**
     * 对列表进行升序排序,为null排在前面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void ascSort(List list, Getter getter) {
        sort(list, getter, true);
    }

    /**
     * 对列表进行降序排序,为null排在前面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void descSort(List list, Getter getter) {
        sort(list, getter, false);
    }

    /**
     * 对列表进行升序排序,为null排在后面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void ascSortNullLast(List list, Getter getter) {
        sortNullLast(list, getter, true);
    }

    /**
     * 对列表进行降序排序,为null排在后面
     * @param list 要排序的列表
     * @param getter 获取要排序的值的方法
     */
    public static  void descSortNullLast(List list, Getter getter) {
        sortNullLast(list, getter, false);
    }

    /**
     * 对比两个值,空值排在前面
     * @param o1 值1
     * @param o2 值2
     * @return 非空的值1 小于、等于、大于 非空的值2 时分别返回 -1、0、1
     */
    public static > int compare(E o1, E o2) {
        return compareNull(o1, o2, false);
    }

    /**
     * 对比两个值,空值排在前面
     * @param o1 值1
     * @param o2 值2
     * @return 非空的值1 小于、等于、大于 非空的值2 时分别返回 -1、0、1
     */
    public static > int nullFirstCompare(E o1, E o2) {
        return compareNull(o1, o2, false);
    }

    /**
     * 对比两个值,空值排在后面
     * @param o1 值1
     * @param o2 值2
     * @return 非空的值1 小于、等于、大于 非空的值2 时分别返回 -1、0、1
     */
    public static > int nullLastCompare(E o1, E o2) {
        return compareNull(o1, o2, true);
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    static int compareNull(Comparable o1, Comparable o2, boolean nullLast) {
        int v = xorCompare(o1, o2, nullLast);
        if (v == 0 && o1 != null && o2 != null) {
            v = o1.compareTo(o2);
        }
        if (v == 0) {
            return 0;
        }
        return v < 0 ? -1 : 1;
    }

    static  int xorCompare(E o1, E o2, boolean nullLast) {
        if (o1 == null) {
            if (o2 != null) {
                return nullLast ? 1 : -1;
            }
        } else if (o2 == null) {
            return nullLast ? -1 : 1;
        }
        return 0;
    }

    /**
     * 包装一个 null 值排在前面的 {@link Comparator} 对象
     * @param comparator 原 {@link Comparator} 对象
     * @return 返回一个 null 值排在前面的 {@link Comparator} 对象
     */
    public static  Comparator nullFirstComparator(Comparator comparator) {
        return nullableComparator(comparator, false);
    }

    /**
     * 包装一个 null 值排在后面的 {@link Comparator} 对象
     * @param comparator 原 {@link Comparator} 对象
     * @return 返回一个 null 值排在后面的 {@link Comparator} 对象
     */
    public static  Comparator nullLastComparator(Comparator comparator) {
        return nullableComparator(comparator, true);
    }

    /**
     * 包装一个支持 null 的 {@link Comparator} 对象
     * @param comparator 原 {@link Comparator} 对象
     * @param nullLast 为 true 时 null 排在后面,否则 null 排在前面
     * @return 返回一个 null 值排在后面的 {@link Comparator} 对象
     */
    public static  Comparator nullableComparator(Comparator comparator, boolean nullLast) {
        return new NullableComparator<>(comparator, nullLast);
    }

    private static class NullableComparator implements Comparator {

        private final Comparator comparator;
        private final boolean nullLast;

        NullableComparator(Comparator comparator, boolean nullLast) {
            this.comparator = comparator;
            this.nullLast = nullLast;
        }

        @Override
        public int compare(E o1, E o2) {
            int v = xorCompare(o1, o2, nullLast);
            if (v == 0 && o1 != null && o2 != null) {
                v = comparator.compare(o1, o2);
            }
            if (v == 0) {
                return 0;
            }
            return v < 0 ? -1 : 1;
        }
    }

    /**
     *
     * @author HeDYn
     *
     * @param 
     */
    public static class ComparatorHelper implements Comparator {

        private final List> comparators;
        private boolean nullLast = false;

        private ComparatorHelper() {
            comparators = new ArrayList<>();
        }

        /**
         * 添加参与对比的属性
         * @param getter 获取属性值的方法
         * @param comparator 用于给属性做对比
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public  ComparatorHelper orderBy(ObjectGetter getter, Comparator comparator) {
            comparators.add(new ObjectGetterComparator<>(this, getter, comparator));
            return this;
        }

        /**
         * 添加参与对比的属性,该属性升序
         * @param getter 获取属性值的方法
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public ComparatorHelper orderBy(Getter getter) {
            comparators.add(new ComparableGetterComparator<>(this, getter));
            return this;
        }

        /**
         * 添加参与对比的属性
         * @param getter 获取属性值的方法
         * @param asc 为true使用升序,为false使用降序
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public ComparatorHelper orderBy(Getter getter, boolean asc) {
            comparators.add(new ComparableGetterComparator<>(this, getter, asc));
            return this;
        }

        /**
         * 添加参与对比的属性,该属性升序
         * @param getter 获取属性值的方法
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public ComparatorHelper ascBy(Getter getter) {
            return orderBy(getter, true);
        }

        /**
         * 添加参与对比的属性,该属性倒序
         * @param getter 获取属性值的方法
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public ComparatorHelper descBy(Getter getter) {
            return orderBy(getter, false);
        }

        /**
         * 为null排在后面
         * @return 返回 {@link ComparatorHelper} 对象
         */
        public ComparatorHelper nullLast() {
            nullLast = true;
            return this;
        }

        /**
         * 对指定的列表进行排序
         * @param list 要排序的列表
         */
        public void sort(List list) {
            Collections.sort(list, this);
        }

        @Override
        public int compare(E o1, E o2) {
            int v = Comparators.xorCompare(o1, o2, nullLast);
            if (v == 0) {
                for (Comparator comparator : comparators) {
                    v = comparator.compare(o1, o2);
                    if (v != 0) {
                        break;
                    }
                }
            }
            return v;
        }

    }
    
    private static class ComparableGetterComparator implements Comparator {

        private final ComparatorHelper helper;
        private final Getter getter;
        private final boolean asc;

        ComparableGetterComparator(ComparatorHelper helper, Getter getter) {
            this(helper, getter, true);
        }

        ComparableGetterComparator(ComparatorHelper helper, Getter getter, boolean asc) {
            this.helper = helper;
            this.getter = getter;
            this.asc = asc;
        }

        @Override
        public int compare(E o1, E o2) {
            Comparable c1 = getter.apply(o1);
            Comparable c2 = getter.apply(o2);
            int v = Comparators.compareNull(c1, c2, helper.nullLast);
            if (asc) {
                return v;
            } else {
                return -v;
            }
        }
    }

    private static class ObjectGetterComparator implements Comparator {

        private final ComparatorHelper helper;
        private final ObjectGetter getter;
        private final Comparator comparator;

        ObjectGetterComparator(ComparatorHelper helper, ObjectGetter getter, Comparator comparator) {
            this.helper = helper;
            this.getter = getter;
            this.comparator = comparator;
        }

        @Override
        public int compare(E o1, E o2) {
            return compareNull(getter.apply(o1), getter.apply(o2));
        }

        private int compareNull(R o1, R o2) {
            int v = xorCompare(o1, o2, helper.nullLast);
            if (v == 0 && o1 != null && o2 != null) {
                v = comparator.compare(o1, o2);
            }
            if (v == 0) {
                return 0;
            }
            return v < 0 ? -1 : 1;
        }
    }

    /**
     *
     * @param 
     */
    public interface Getter {

        Comparable apply(E o);

    }

    /**
     *
     * @param 
     * @param 
     */
    public interface ObjectGetter {

        R apply(E o);

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy