com.feilong.core.util.SortUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of feilong Show documentation
Show all versions of feilong Show documentation
feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.
/*
* 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;
/**
* 专注于排序的工具类.
*
* 说明:
*
*
* - 该类的初衷之一,通常如果直接使用jdk里面的sort方法,比如
*
*
* {@link java.util.Arrays#sort(Object[])}
*
*
* 或者
*
*
* {@link java.util.Collections#sort(List)}
*
*
* 由于这些方法是 void类型的,通常我们需要写2至3行代码
*
*
* - 第二,该类对bean list的排序更加简单便捷
*
*
*
* @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
进行排序.
*
* 说明:
*
*
* - {@link java.util.Collections#sort(List) Collections.sort} 底层就是调用的是 {@link java.util.Arrays#sort(Object[]) Arrays.sort}
*
*
*
* 示例:
*
*
*
*
* 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
进行排序.
*
* 说明:
*
*
* - 默认使用的是 {@link UnknownObjectBehavior#AFTER} ,不在指定固定顺序的元素将排在后面
*
*
*
* 示例:
*
*
*
*
* 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
进行排序.
*
* 说明:
*
*
* - 默认使用的是 {@link UnknownObjectBehavior#AFTER} ,不在指定固定顺序的元素将排在后面
*
*
*
* 示例:
*
*
*
*
* 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顺序排序.
*
* 注意:
*
*
* - 原
map
的顺序不变
* - 该方法使用了 {@link PropertyComparator},允许 null key,null key排在最前面
* -
* 如果直接使用 {@link java.util.TreeMap#TreeMap(Map)},TreeMap不允许 key是null,如果有key是null,那么将会抛出{@link NullPointerException}
*
*
*
*
*
* 示例:
*
*
*
* 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 倒序排序.
*
* 注意:
*
*
* - 原
map
的顺序不变
* - 该方法使用了 {@link PropertyComparator},允许 null key,null key排在最后面
*
*
*
* 示例:
*
*
*
* 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 指定名字顺序排序.
*
* 注意:
*
*
* - 原
map
的顺序不变
*
*
*
* 示例:
*
*
*
* 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).
*
* 注意:
*
*
* - 原
map
的顺序不变
*
*
*
* 示例:
*
*
*
* 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).
*
* 注意:
*
*
* - 原
map
的顺序不变
*
*
*
* 示例:
*
*
*
* 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
进行排序.
*
* 说明:
*
*
* - 原
map
的顺序不变
* - 由于是对{@link java.util.Map.Entry Entry}排序的, 既可以按照key来排序,也可以按照value来排序哦
*
*
*
* 示例:
*
*
* 比如有以下的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));
}
}