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

com.feilong.core.util.comparator.BeanComparatorUtil Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Copyright (C) 2008 feilong
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.feilong.core.util.comparator;

import static com.feilong.core.bean.ConvertUtil.toList;
import static com.feilong.core.util.CollectionsUtil.newArrayList;
import static com.feilong.core.util.comparator.SortHelper.isAsc;
import static com.feilong.lib.collection4.ComparatorUtils.reversedComparator;

import java.util.Comparator;
import java.util.List;

import com.feilong.core.Validate;
import com.feilong.lib.beanutils.BeanComparator;
import com.feilong.lib.collection4.ComparatorUtils;
import com.feilong.lib.collection4.comparators.ComparableComparator;
import com.feilong.lib.collection4.comparators.FixedOrderComparator;
import com.feilong.lib.collection4.comparators.FixedOrderComparator.UnknownObjectBehavior;

/**
 * 专注于 bean 属性值的排序.
 *
 * @author feilong
 * @see "org.apache.commons.collections4.ComparatorUtils"
 * @see FixedOrderComparator
 * @since 1.8.0
 */
@SuppressWarnings("squid:S1192") //String literals should not be duplicated
public final class BeanComparatorUtil{

    /** Don't let anyone instantiate this class. */
    private BeanComparatorUtil(){
        //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化.
        //see 《Effective Java》 2nd
        throw new AssertionError("No " + getClass().getName() + " instances for you!");
    }

    //---------------------------------------------------------------

    /**
     * 按照不同指定属性 propertyNameAndOrders 排序的 {@link Comparator}.
     *
     * @param 
     *            the generic type
     * @param propertyNameAndOrders
     *            属性名称和排序因子,
     * 
     *            

* 格式可以是纯的属性名称, 比如 "name"; 也可以是属性名称+排序因子(以空格分隔),比如 "name desc" *

* *

说明:

*
* *
*
关于属性名称
*
* 泛型T对象指定的属性名称,Possibly indexed and/or nested name of the property to be * modified,参见propertyName,
* 该属性对应的value 必须实现 {@link Comparable}接口. *
* *
关于排序因子
*
* 可以没有排序因子
* 如果有,值可以是asc(顺序),desc(倒序)两种;
* 如果没有,默认按照asc(顺序)排序;
* 此外,asc/desc忽略大小写 *
* *
* *
* @return 如果propertyNameAndOrders是单值,那么直接调用 {@link #propertyComparator(String)} 返回 * @throws NullPointerException * 如果 propertyNameAndOrders 是null,
* 或者有元素是 null; * @throws IllegalArgumentException * 如果 propertyNameAndOrders 是empty,
* 或者有元素是 blank * @see "org.apache.commons.collections4.ComparatorUtils#chainedComparator(java.util.Collection)" * @since 1.10.2 support propertyNameAndOrder */ public static Comparator chainedComparator(String...propertyNameAndOrders){ Validate.notEmpty(propertyNameAndOrders, "propertyNameAndOrders can't be null/empty!"); //如果propertyNameAndOrders是单值,那么直接调用 com.feilong.core.util.comparator.BeanComparatorUtil.propertyComparator(String) 返回 if (1 == propertyNameAndOrders.length){ return propertyComparator(propertyNameAndOrders[0]); } //--------------------------------------------------------------- List> comparators = newArrayList(); for (String propertyNameAndOrder : propertyNameAndOrders){ Validate.notBlank(propertyNameAndOrder, "propertyNameAndOrder can't be blank!"); String[] propertyNameAndOrderArray = SortHelper.parsePropertyNameAndOrder(propertyNameAndOrder); //注意:此处不要使用 propertyComparator(propertyName) //因为,PropertyComparator 如果属性值相同,会使用其他规则继续比较(为了TreeMap/treeSet),也就是说,一般而言一次就比较出顺序,后续的propertyNameAndOrders 就没作用了 ComparableComparator comparableComparator = ComparableComparator.comparableComparator(); Comparator instance = ComparatorUtils.nullHighComparator(comparableComparator); //null排在最后面 BeanComparator beanComparator = new BeanComparator<>(propertyNameAndOrderArray[0], instance); comparators.add(isAsc(propertyNameAndOrderArray) ? beanComparator : reversedComparator(beanComparator)); } return ComparatorUtils.chainedComparator(comparators); } //--------------------------------------------------------------- /** * 指定属性 propertyName ,按照自然顺序 排序的 {@link Comparator}. * * @param * the generic type * @param propertyNameAndOrder * 属性名称和排序因子, * *

* 格式可以是纯的属性名称, 比如 "name"; 也可以是属性名称+排序因子(以空格分隔),比如 "name desc" *

* *

说明:

*
* *
*
关于属性名称
*
* 泛型T对象的属性名称,Possibly indexed and/or nested name of the property to be * modified,参见propertyName,
* 该属性对应的value 必须实现 {@link Comparable}接口. *
* *
关于排序因子
*
* 可以没有排序因子
* 如果有,值可以是asc(顺序),desc(倒序)两种;
* 如果没有,默认按照asc(顺序)排序;
* 此外,asc/desc忽略大小写 *
* *
* *
* @return {@link PropertyComparator} * @throws NullPointerException * 如果 propertyNameAndOrder 是null * @throws IllegalArgumentException * 如果 propertyNameAndOrder 是blank * @see PropertyComparator#PropertyComparator(String) */ public static Comparator propertyComparator(String propertyNameAndOrder){ Validate.notBlank(propertyNameAndOrder, "propertyNameAndOrder can't be blank!"); String[] propertyNameAndOrderArray = SortHelper.parsePropertyNameAndOrder(propertyNameAndOrder); PropertyComparator propertyComparator = new PropertyComparator<>(propertyNameAndOrderArray[0]); return isAsc(propertyNameAndOrderArray) ? propertyComparator : reversedComparator(propertyComparator); } //--------------------------------------------------------------- /** * 指定属性 propertyName 按照固定顺序值 propertyValues 排序的 {@link Comparator}. * * @param * the generic type * @param * the value type * @param propertyName * 泛型T对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName,该属性对应的value 必须实现 {@link Comparable}接口. * @param propertyValues * the property values * @return the comparator * @throws NullPointerException * 如果 propertyName 是null,或者propertyValues 是null * @throws IllegalArgumentException * 如果 propertyName 是blank * @see #propertyComparator(String, List) */ @SafeVarargs public static Comparator propertyComparator(String propertyName,V...propertyValues){ Validate.notBlank(propertyName, "propertyName can't be blank!"); Validate.notNull(propertyValues, "propertyValues can't be null!"); return propertyComparator(propertyName, toList(propertyValues)); } /** * 指定属性 propertyName 按照固定顺序值 propertyValues 排序的 {@link Comparator}. * *

* 调用 #propertyComparator(String, List, UnknownObjectBehavior),默认 {@link UnknownObjectBehavior#AFTER} *

* * @param * the generic type * @param * the value type * @param propertyName * 泛型T对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName,该属性对应的value 必须实现 {@link Comparable}接口. * @param propertyValues * the property values * @return the comparator * @throws NullPointerException * 如果 propertyName 是null,或者propertyValues 是null * @throws IllegalArgumentException * 如果 propertyName 是blank */ public static Comparator propertyComparator(String propertyName,List propertyValues){ Validate.notBlank(propertyName, "propertyName can't be blank!"); Validate.notNull(propertyValues, "propertyValues can't be null!"); return propertyComparator(propertyName, propertyValues, UnknownObjectBehavior.AFTER); } /** * 指定属性 propertyName 按照固定顺序值 propertyValues,并且可以指定 unknownObjectBehavior 排序的 {@link Comparator}. * * @param * the generic type * @param * the value type * @param propertyName * 泛型T对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName,该属性对应的value 必须实现 {@link Comparable}接口. * @param propertyValues * the property values * @param unknownObjectBehavior * the unknown object behavior * @return the comparator * @throws NullPointerException * 如果 propertyName 是null,或者propertyValues 是null * @throws IllegalArgumentException * 如果 propertyName 是blank * @see PropertyComparator#PropertyComparator(String, Comparator) * @see FixedOrderComparator#FixedOrderComparator(List) * @since 1.8.2 */ public static Comparator propertyComparator( String propertyName, List propertyValues, UnknownObjectBehavior unknownObjectBehavior){ Validate.notBlank(propertyName, "propertyName can't be blank!"); Validate.notNull(propertyValues, "propertyValues can't be null!"); FixedOrderComparator fixedOrderComparator = ComparatorUtil.buildFixedOrderComparator(propertyValues, unknownObjectBehavior); return new PropertyComparator<>(propertyName, fixedOrderComparator); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy