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

com.feilong.core.util.SortUtil 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;

import static com.feilong.core.Validator.isNullOrEmpty;
import static com.feilong.core.bean.ConvertUtil.toArray;
import static com.feilong.core.bean.ConvertUtil.toList;
import static com.feilong.core.bean.ConvertUtil.toMap;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;

import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

import com.feilong.core.util.comparator.BeanComparatorUtil;
import com.feilong.core.util.comparator.ComparatorUtil;
import com.feilong.core.util.comparator.PropertyComparator;
import com.feilong.lib.collection4.ComparatorUtils;
import com.feilong.lib.collection4.comparators.ReverseComparator;
import com.feilong.lib.collection4.comparators.FixedOrderComparator.UnknownObjectBehavior;
import com.feilong.core.Validate;

/**
 * 专注于排序的工具类.
 * 
 * 

说明:

*
*
    *
  1. 该类的初衷之一,通常如果直接使用jdk里面的sort方法,比如 * *
     * {@link java.util.Arrays#sort(Object[])}
     * 
    * * 或者 * *
     * {@link java.util.Collections#sort(List)}
     * 
    * * 由于这些方法是 void类型的,通常我们需要写2至3行代码 * *
  2. *
  3. 第二,该类对bean list的排序更加简单便捷
  4. *
*
* * @author feilong * @since 1.8.0 */ public final class SortUtil{ /** Don't let anyone instantiate this class. */ private SortUtil(){ //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化. //see 《Effective Java》 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } //--------------------------------------------------------------- /** * 对 数组 arrays 进行排序. * *

示例:

* *
* *
     * sortArray(toArray(5, 10, 3, 2)  =   [2,3,5,10]
     * 
* *
* *

以前代码需要写成:

* *
* *
     * 
     * public static String toSalesPropertiesIdsJson(Long...itemPropertiesIdLongs){
     *     Arrays.sort(itemPropertiesIdLongs);
     *     return JsonUtil.format(itemPropertiesIdLongs, 0, 0);
     * }
     * 
     * 
* * 现在可以重构成: * *
     * 
     * public static String toSalesPropertiesIdsJson(Long...itemPropertiesIdLongs){
     *     return JsonUtil.format(sortArray(itemPropertiesIdLongs), 0, 0);
     * }
     * 
* * 再如: * *
     * 
     * // 得到默认分类,目前是最小的
     * private Long getDefaultCategoryId(Long[] categoriesIds){
     *     Arrays.sort(categoriesIds);
     *     return categoriesIds[0];
     * }
     * 
     * 
* * 可以重构成: * *
     * 
     * // 得到默认分类,目前是最小的
     * private Long getDefaultCategoryId(Long[] categoriesIds){
     *     return sortArray(categoriesIds)[0];
     * }
     * 
* *
* * @param * the generic type * @param arrays * the arrays * @return 如果 array 是null,返回 empty array
* @see java.util.Arrays#sort(Object[]) * @since 1.8.7 change T... to T[] */ public static T[] sortArray(T[] arrays){//此处定义为 T[] 而不是 T...,为了避免 jdk8以下的版本 sort(strs, fixedOrderComparator); 编译不通过 if (null == arrays){ return toArray(); } Arrays.sort(arrays); return arrays; } /** * 对 数组 arrays使用 comparator 进行排序. * *

示例:

* *
* *

* 场景: 对字符串数组先按照长度比较,如果长度相等,那么再按照字母比较 *

* *
     * 
     * String[] arrays = { "almn", "fba", "cba" };
     * 
     * Comparator{@code } comparator = new Comparator{@code }(){
     * 
     *     @Override
     *     public int compare(String s1,String s2){
     *         Integer length = s1.length();
     *         Integer length2 = s2.length();
     * 
     *         //先判断长度,长度比较
     *         int compareTo = length.compareTo(length2);
     * 
     *         //如果长度相等,那么比较自己本身的顺序
     *         if (0 == compareTo){
     *             compareTo = s1.compareTo(s2);
     *         }
     *         return compareTo;
     *     }
     * };
     * sortArray(arrays, comparator);
     * 
     * assertArrayEquals(toArray("cba", "fba", "almn"), arrays);
     * 
     * 
* *
* * @param * the generic type * @param arrays * the arrays * @param comparators * the comparators * @return 如果 array 是null,返回 empty array
* 如果 comparators 是null或者empty,直接返回 arrays
* @see java.util.Arrays#sort(Object[], Comparator) * @since 1.8.2 change to varargs parameter comparator * @since 1.8.7 change method name */ @SafeVarargs public static T[] sortArray(T[] arrays,Comparator...comparators){ if (null == arrays){ return toArray(); } if (isNullOrEmpty(comparators)){ return arrays; } Arrays.sort(arrays, toComparator(comparators)); return arrays; } //--------------------------------------------------------------- /** * 对 集合 list 进行排序. * *

说明:

*
*
    *
  1. {@link java.util.Collections#sort(List) Collections.sort} 底层就是调用的是 {@link java.util.Arrays#sort(Object[]) Arrays.sort}
  2. *
*
* *

示例:

* *
* *
     * sortList(toList(5, 10, 3, 2))       = [2,3,5,10]
     * 
* *
* * @param * the generic type * @param list * the list * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* @see java.util.Collections#sort(List) * @since 1.8.7 change method name */ public static > List sortList(List list){ if (null == list){ return emptyList(); } Collections.sort(list); return list; } //--------------------------------------------------------------- /** * 对 集合 list 按照指定的固定顺序 fixedOrderItems 进行排序. * *

说明:

*
*
    *
  1. 默认使用的是 {@link UnknownObjectBehavior#AFTER} ,不在指定固定顺序的元素将排在后面
  2. *
*
* *

示例:

* *
* *
     * assertThat(
     *                 sortListByFixedOrderArray(toList("张飞", "关羽", "刘备"), toArray("刘备", "张飞", "关羽")), //
     *                 contains("刘备", "张飞", "关羽"));
     * 
* *
* *

重构:

* *
*

* 对于以下代码: *

* *
     * 
     * try{
     *     Collections.sort(
     *                     list,
     *                     new FixedOrderComparator{@code <>}(
     *                                     StoPropertyConstants.PRPT_ITEM_HYPELAUNCH,
     *                                     StoPropertyConstants.PRPT_ITEM_PRESONALLZATION_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_PERSALES_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_VIP_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_COMINGSOON_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_DISCOUNT_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_NORMAL_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_NOSALE));
     * }catch (Exception e){
     *     LOGGER.error("itemType sort error:{},itemType:{}", e, JsonUtil.format(itemType));
     * }
     * 
     * 
* * 可以重构成: * *
     * com.feilong.core.util.SortUtil.sortListByFixedOrderArray(
     *                 list,
     *                 StoPropertyConstants.PRPT_ITEM_HYPELAUNCH,
     *                 StoPropertyConstants.PRPT_ITEM_PRESONALLZATION_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_PERSALES_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_VIP_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_COMINGSOON_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_DISCOUNT_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_NORMAL_CODE,
     *                 StoPropertyConstants.PRPT_ITEM_NOSALE);
     * 
* *
* * @param * the generic type * @param list * the list * @param fixedOrderItems * the fixed order items * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* 如果 list 是empty,返回 list
* 如果 fixedOrderItems 是null或者是 empty,返回 list
* @see java.util.Collections#sort(List) * @since 1.14.3 */ @SafeVarargs public static > List sortListByFixedOrderArray(List list,T...fixedOrderItems){ return sortListByFixedOrderList(list, toList(fixedOrderItems)); } /** * 对 集合 list 按照指定的固定顺序 fixedOrderItemList 进行排序. * *

说明:

*
*
    *
  1. 默认使用的是 {@link UnknownObjectBehavior#AFTER} ,不在指定固定顺序的元素将排在后面
  2. *
*
* *

示例:

* *
* *
     * assertThat(
     *                 sortListByFixedOrderList(toList("张飞", "关羽", "刘备"), toList("刘备", "张飞", "关羽")), //
     *                 contains("刘备", "张飞", "关羽"));
     * 
* *
*

重构:

* *
*

* 对于以下代码: *

* *
     * 
     * try{
     *     Collections.sort(
     *                     list,
     *                     new FixedOrderComparator{@code <>}(
     *                                     StoPropertyConstants.PRPT_ITEM_HYPELAUNCH,
     *                                     StoPropertyConstants.PRPT_ITEM_PRESONALLZATION_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_PERSALES_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_VIP_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_COMINGSOON_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_DISCOUNT_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_NORMAL_CODE,
     *                                     StoPropertyConstants.PRPT_ITEM_NOSALE));
     * }catch (Exception e){
     *     LOGGER.error("itemType sort error:{},itemType:{}", e, JsonUtil.format(itemType));
     * }
     * 
     * 
* * 可以重构成: * *
     * com.feilong.core.util.SortUtil.sortListByFixedOrderList(
     *                 list,
     *                 toList(
     *                                 StoPropertyConstants.PRPT_ITEM_HYPELAUNCH,
     *                                 StoPropertyConstants.PRPT_ITEM_PRESONALLZATION_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_PERSALES_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_VIP_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_COMINGSOON_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_DISCOUNT_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_NORMAL_CODE,
     *                                 StoPropertyConstants.PRPT_ITEM_NOSALE));
     * 
* *
* * @param * the generic type * @param list * the list * @param fixedOrderItemList * the fixed order item list * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* 如果 list 是empty,返回 list
* 如果 fixedOrderItemList 是null或者是 empty,返回 list
* @see java.util.Collections#sort(List) * @see com.feilong.core.util.comparator.ComparatorUtil#buildFixedOrderComparator(List) * @since 1.14.3 */ public static > List sortListByFixedOrderList(List list,List fixedOrderItemList){ if (null == list){ return emptyList(); } if (isNullOrEmpty(list)){ return list; } if (isNullOrEmpty(fixedOrderItemList)){ return list; } return sortList(list, ComparatorUtil.buildFixedOrderComparator(fixedOrderItemList)); } //--------------------------------------------------------------- /** * 对集合 list,使用指定的 comparators 进行排序. * *

示例:

* *
* *

* 场景: 将 user list 按照 id进行排序 *

* *
     * List{@code } list = new ArrayList{@code <>}();
     * list.add(new User(12L, 18));
     * list.add(new User(2L, 36));
     * list.add(new User(5L, 22));
     * list.add(new User(1L, 8));
     * 
     * SortUtil.sortList(list, new PropertyComparator{@code }("id"));
     * LOGGER.debug(JsonUtil.format(list));
     * 
* * 返回: * *
     * [
     *  {"id": 1,"age": 8},
     *  {"id": 2,"age": 36},
     *  {"id": 5,"age": 22},
     *  {"id": 12,"age": 18}
     * ]
     * 
* *

* 当然对于上述示例,你可以直接调用: *

* *
     * {@link #sortListByPropertyNamesValue(List, String...) SortUtil.sortListByPropertyNamesValue(list, "id");}
     * 
* * *

* 我们再来个复杂点的例子: 将 user list 按照 "刘备" 排在 "关羽" 前面 进行排序,如果名字相同再按照 age进行排序 *

* *
     * User guanyu = new User("关羽", 30);
     * 
     * User liubei60 = new User("刘备", 60);
     * User liubei25 = new User("刘备", 25);
     * User liubei30 = new User("刘备", 30);
     * User liubei10 = new User("刘备", 10);
     * 
     * String[] names = { "刘备", "关羽" };
     * List{@code } list = CollectionsUtil.select(toList(liubei60, liubei30, liubei10, guanyu, liubei25), "name", names);
     * sortList(
     *                 list, //
     *                 new PropertyComparator{@code }("name", new FixedOrderComparator{@code <>}(names)),
     *                 new PropertyComparator{@code }("age"));
     * 
* * 返回: * *
     * assertThat(list, contains(liubei10, liubei25, liubei30, liubei60, guanyu));
     * 
* *
* * @param * the generic type * @param list * the list * @param comparators * the comparators * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* 如果 comparators 是null或者empty,直接返回 list
* 如果 comparators length ==1,取 comparators[0]做排序;
* 如果 {@code comparators length > 1},转成 {@link ComparatorUtils#chainedComparator(Comparator...)}排序; * @see java.util.Collections#sort(List, Comparator) * @since 1.8.2 * @since 1.8.7 change method name */ @SafeVarargs public static List sortList(List list,Comparator...comparators){ if (null == list){ return emptyList(); } if (isNullOrEmpty(comparators)){ return list; } Collections.sort(list, toComparator(comparators)); return list; } /** * 如果 comparators length ==1,返回 comparators[0]; 否则返回 {@link ComparatorUtils#chainedComparator(Comparator...)}; * * @param * the generic type * @param comparators * the comparators * @return the comparator * @since 1.8.2 */ @SafeVarargs private static Comparator toComparator(Comparator...comparators){ return 1 == comparators.length ? comparators[0] : ComparatorUtils.chainedComparator(comparators); } //--------------------------------------------------------------- /** * 对集合 list,按照指定属性的值(组合)进行排序. * *

示例:

* *
* *

* 场景: 将user list 先按照 id 再按照 age 进行排序 *

* *
     * List{@code } list = new ArrayList{@code <>}();
     * list.add(new User(12L, 18));
     * list.add(new User(2L, 36));
     * list.add(new User(2L, 2));
     * list.add(new User(2L, 30));
     * list.add(new User(1L, 8));
     * 
     * SortUtil.sortListByPropertyNamesValue(list, "id", "age");
     * 
     * LOGGER.debug(JsonUtil.formatWithIncludes(list, "id", "age"));
     * 
* * 返回: * *
     * [
     *  {"id": 1,"age": 8},
     *  {"id": 2,"age": 2},
     *  {"id": 2,"age": 30},
     *  {"id": 2,"age": 36},
     *  {"id": 12,"age": 18}
     * ]
     * 
* * 你还可以 * *

* 场景: 将user list 先按照 id desc 再按照 age asc 进行排序 *

* *
     * User id12_age18 = new User(12L, 18);
     * User id1_age8 = new User(1L, 8);
     * User id2_age30 = new User(2L, 30);
     * User id2_age2 = new User(2L, 2);
     * User id2_age36 = new User(2L, 36);
     * List{@code } list = toList(id12_age18, id2_age36, id2_age2, id2_age30, id1_age8);
     * 
     * sortListByPropertyNamesValue(list, "id desc", "age");
     * 
     * assertThat(list, contains(id12_age18, id2_age2, id2_age30, id2_age36, id1_age8));
     * 
* *
* * @param * the generic type * @param list * the list * @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 如果 list 是null,返回 {@link Collections#emptyList()}
* @throws NullPointerException * 如果 propertyNames 是null * @throws IllegalArgumentException * 如果 propertyNames 是empty ,或者有 null元素 * @see BeanComparatorUtil#chainedComparator(String...) * @see com.feilong.lib.collection4.ComparatorUtils#chainedComparator(java.util.Comparator...) * @see #sortList(List, Comparator...) * @since 1.8.7 change name */ public static List sortListByPropertyNamesValue(List list,String...propertyNameAndOrders){ if (null == list){ return emptyList(); } Validate.notEmpty(propertyNameAndOrders, "propertyNameAndOrders can't be null/empty!"); Validate.noNullElements(propertyNameAndOrders, "propertyNameAndOrders:[%s] has empty value", propertyNameAndOrders); Comparator comparator = BeanComparatorUtil.chainedComparator(propertyNameAndOrders); return sortList(list, comparator); } //--------------------------------------------------------------- /** * 对 集合 list,属性 propertyName 按照固定顺序值 propertyValues 进行排序. * *

示例:

* *
* *

* 场景: 将user list中 "刘备" 排在 "关羽"前面 *

* *
     * User zhangfei = new User("张飞", 23);
     * User guanyu = new User("关羽", 30);
     * User liubei = new User("刘备", 25);
     * List{@code } list = toList(zhangfei, guanyu, liubei);
     * 
     * List{@code } resultList = CollectionsUtil.select(list, "name", "刘备", "关羽");
     * Collections.sort(resultList, new PropertyComparator{@code }("name", new FixedOrderComparator{@code <>}("刘备", "关羽")));
     * 
* *

* 此时你可以直接调用: *

* *
     * List{@code } resultList = CollectionsUtil.select(list, "name", "刘备", "关羽");
     * SortUtil.sortListByFixedOrderPropertyValueArray(resultList, "name", "刘备", "关羽"));
     * 
* * 返回: * *
     * assertThat(resultList, contains(liubei, guanyu));
     * 
* *
* * @param * the generic type * @param * the value type * @param list * the list * @param propertyName * 泛型O对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName * @param propertyValues * the property values * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* @throws NullPointerException * 如果 propertyName 是null,或者 propertyValues 是null * @throws IllegalArgumentException * 如果 propertyName 是blank * @see BeanComparatorUtil#propertyComparator(String, Object...) * @see #sortList(List, Comparator...) * @since 1.8.7 change method name */ @SafeVarargs public static List sortListByFixedOrderPropertyValueArray(List list,String propertyName,V...propertyValues){ if (null == list){ return emptyList(); } Validate.notBlank(propertyName, "propertyName can't be blank!"); Comparator propertyComparator = BeanComparatorUtil.propertyComparator(propertyName, propertyValues); return sortList(list, propertyComparator); } /** * 对 集合 list,属性 propertyName 按照固定顺序值 propertyValues 进行排序. * *

示例:

* *
* *

* 场景: 将user list中 "刘备" 排在 "关羽"前面 *

* *
     * 
     * User zhangfei = new User("张飞", 23);
     * User guanyu = new User("关羽", 30);
     * User liubei = new User("刘备", 25);
     * List{@code } list = toList(zhangfei, guanyu, liubei);
     * 
     * List{@code } returnList = CollectionsUtil.select(list, "name", toList("刘备", "关羽"));
     * returnList = sortListByFixedOrderPropertyValueList(returnList, "name", toList("刘备", "关羽"));
     * 
* * 返回: * *
     * assertThat(returnList, contains(liubei, guanyu));
     * 
* *
* * @param * the generic type * @param * the value type * @param list * the list * @param propertyName * 泛型O对象指定的属性名称,Possibly indexed and/or nested name of the property to be modified,参见 * propertyName * @param propertyValues * the property values * @return 如果 list 是null,返回 {@link Collections#emptyList()}
* @throws NullPointerException * 如果 propertyName 是null * @throws IllegalArgumentException * 如果 propertyName 是blank * @see BeanComparatorUtil#propertyComparator(String, List) * @see #sortList(List, Comparator...) * @since 1.8.7 change method name */ public static List sortListByFixedOrderPropertyValueList(List list,String propertyName,List propertyValues){ if (null == list){ return emptyList(); } Validate.notBlank(propertyName, "propertyName can't be blank!"); Comparator propertyComparator = BeanComparatorUtil.propertyComparator(propertyName, propertyValues); return sortList(list, propertyComparator); } //--------------------------------------------------------------- /** * 按照key asc顺序排序. * *

注意:

*
*
    *
  1. map 的顺序不变
  2. *
  3. 该方法使用了 {@link PropertyComparator},允许 null key,null key排在最前面
  4. *
  5. * 如果直接使用 {@link java.util.TreeMap#TreeMap(Map)},TreeMap不允许 key是null,如果有key是null,那么将会抛出{@link NullPointerException}
    *
  6. * *
*
* *

示例:

*
* *
     * Map{@code } map = new HashMap{@code <>}();
     * 
     * map.put("a", 123);
     * map.put("c", 345);
     * map.put(null, 1345);
     * map.put("b", 8);
     * 
     * LOGGER.debug(JsonUtil.format(SortUtil.sortMapByKeyAsc(map)));
     * 
* * 返回: * *
     * {
     * null: 1345,
     * "a": 123,
     * "b": 8,
     * "c": 345
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* @see java.util.TreeMap#TreeMap(Map) * @since 1.8.0 move from MapUtil * @since 1.8.7 change method name */ public static Map sortMapByKeyAsc(Map map){ if (null == map){ return emptyMap(); } return sortMap(map, new PropertyComparator>("key")); } /** * 按照key desc 倒序排序. * *

注意:

*
*
    *
  1. map 的顺序不变
  2. *
  3. 该方法使用了 {@link PropertyComparator},允许 null key,null key排在最后面
  4. *
*
* *

示例:

*
* *
     * Map{@code } map = new HashMap{@code <>}();
     * 
     * map.put("a", 123);
     * map.put("c", 345);
     * map.put(null, 88);
     * map.put("b", 8);
     * 
     * LOGGER.debug(JsonUtil.format(SortUtil.sortMapByKeyDesc(map)));
     * 
* * 返回: * *
     * {
     * "c": 345,
     * "b": 8,
     * "a": 123,
     * null: 88
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* @see ReverseComparator#ReverseComparator(Comparator) * @see PropertyComparator#PropertyComparator(String) * @see #sortMap(Map, Comparator) * @since 1.8.0 move from MapUtil * @since 1.8.7 change method name */ public static Map sortMapByKeyDesc(Map map){ if (null == map){ return emptyMap(); } return sortMap(map, new ReverseComparator>(new PropertyComparator>("key"))); } //--------------------------------------------------------------- /** * 按照key 指定名字顺序排序. * *

注意:

*
*
    *
  1. map 的顺序不变
  2. *
*
* *

示例:

*
* *
     * Map{@code } map = new HashMap{@code <>}();
     * 
     * map.put("DE", 99);
     * map.put("L", 3428);
     * map.put("O", 13);
     * map.put("UN", 17);
     * map.put("S", 6);
     * 
     * //L-上市,S-暂停,DE-终止上市,UN-未上市
     * Map{@code } sortByKeyAsc = sortMapByKeyFixOrder(map, "L", "UN", "DE", "S", "O");
     * 
     * LOGGER.debug(JsonUtil.format(sortByKeyAsc));
     * 
* * 返回: * *
    {
        "L": 3428,
        "UN": 17,
        "S": 6,
        "DE": 99,
        "O": 13
    }
     * 
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @param keys * the keys * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* 如果 keys 是null或者empty,原样返回 map
* @see PropertyComparator#PropertyComparator(String) * @see #sortMap(Map, Comparator) * @since 1.10.6 */ public static Map sortMapByKeyFixOrder(Map map,K...keys){ if (null == map){ return emptyMap(); } //--------------------------------------------------------------- if (isNullOrEmpty(keys)){ return map; } //--------------------------------------------------------------- Comparator> propertyComparator = BeanComparatorUtil.propertyComparator("key", keys); return sortMap(map, propertyComparator); } //------------------------sortMapByValue--------------------------------------- /** * 根据value 来顺序排序(asc). * *

注意:

*
*
    *
  1. map 的顺序不变
  2. *
*
* *

示例:

*
* *
     * Map{@code } map = new HashMap{@code <>}();
     * map.put("a", 123);
     * map.put("c", 345);
     * map.put("b", 8);
     * LOGGER.debug(JsonUtil.format(SortUtil.sortMapByValueAsc(map)));
     * 
* * 返回: * *
     * {
     * "b": 8,
     * "a": 123,
     * "c": 345
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* @see #sortMap(Map, Comparator) * @since 1.8.0 move from MapUtil * @since 1.8.7 change name from sortByValueAsc */ public static > Map sortMapByValueAsc(Map map){ if (null == map){ return emptyMap(); } return sortMap(map, new PropertyComparator>("value")); } /** * 根据value 来倒序排序(desc). * *

注意:

*
*
    *
  1. map 的顺序不变
  2. *
*
* *

示例:

*
* *
     * Map{@code } map = new LinkedHashMap{@code <>}();
     * 
     * map.put("a", 123);
     * map.put("c", 345);
     * map.put("b", 8);
     * 
     * LOGGER.debug(JsonUtil.format(SortUtil.sortMapByValueDesc(map)));
     * 
* * 返回: * *
     * {
     * "c": 345,
     * "a": 123,
     * "b": 8
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* @see #sortMap(Map, Comparator) * @since 1.8.0 move from MapUtil * @since 1.8.7 change method name from sortByValueDesc */ public static > Map sortMapByValueDesc(Map map){ if (null == map){ return emptyMap(); } return sortMap(map, new ReverseComparator>(new PropertyComparator>("value"))); } //--------------------------------------------------------------- /** * 使用 基于 {@link java.util.Map.Entry Entry} 的 mapEntryComparator 来对 map进行排序. * *

说明:

*
*
    *
  1. map 的顺序不变
  2. *
  3. 由于是对{@link java.util.Map.Entry Entry}排序的, 既可以按照key来排序,也可以按照value来排序哦
  4. *
*
* *

示例:

*
* * 比如有以下的map * *
     * Map{@code } map = new HashMap{@code <>}();
     * 
     * map.put("a13", 123);
     * map.put("a2", 345);
     * map.put("a8", 8);
     * 
* * 如果我们只是使用 : * *
     * LOGGER.debug(JsonUtil.format(SortUtil.sortByKeyAsc(map)));
     * 
* * 返回: * *
     * {
     * "a13": 123,
     * "a2": 345,
     * "a8": 8
     * }
     * 
* * 此时可以看出 a13是以字符串的形式进行比较的,我们可以使用以下的自定义的 Comparator,来达到排序的效果 * *
     * PropertyComparator{@code >} propertyComparator = new PropertyComparator{@code >}(
     *                 "key",
     *                 new RegexGroupNumberComparator("a(\\d*)"));
     * LOGGER.debug(JsonUtil.format(SortUtil.sortMap(map, propertyComparator)));
     * 
* * 返回: * *
     * {
     * "a2": 345,
     * "a8": 8,
     * "a13": 123
     * }
     * 
* *
* * @param * the key type * @param * the value type * @param map * the map * @param mapEntryComparator * 基于 {@link java.util.Map.Entry Entry} 的 {@link Comparator} * @return 如果 map 是null,返回 {@link Collections#emptyMap()}
* 如果 mapEntryComparator 是null,抛出 {@link NullPointerException}
* @see java.util.Collections#sort(List, Comparator) * @since 1.8.0 move from MapUtil * @since 1.8.7 change method name from sort */ public static Map sortMap(Map map,Comparator> mapEntryComparator){ if (null == map){ return emptyMap(); } Validate.notNull(mapEntryComparator, "mapEntryComparator can't be null!"); List> mapEntryList = toList(map.entrySet()); return toMap(sortList(mapEntryList, mapEntryComparator)); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy