集合处理利器 - CollectionsUtil 在我们日常开发工作中, 大部分时间其实都是在和 JAVA集合框架打交道,对集合框架使用溜的话,会非常快捷,下面特别封装十分常用的方法 主要由下面8部分组成:  ## 1.辅助添加 方法 | Description :---- | :--------- **addAllIgnoreNull**(Collection<O>, Iterable<? extends O>) | 添加所有的Iterable元素到指定的objectCollection,如果 iterable是null将忽略. **addIgnoreNullOrEmpty**(Collection<T>, T) | 添加 element元素到指定的objectCollection,如果 element 是null或者 empty将忽略. ### 1.1 **addAllIgnoreNull**(Collection<O>, Iterable<? extends O>) 对于以下代码: ```JAVA private Set<String> getItemComboIds(List<ShoppingCartLineCommand> lines){ Set<String> set = new HashSet<>(); if (null != lines && lines.size() > 0){ for (ShoppingCartLineCommand line : lines){ if (line.getComboIds() != null){ set.addAll(line.getComboIds()); } } } return set; } ``` **可以重构成: ** ```JAVA private Set<String> getItemComboIds(List<ShoppingCartLineCommand> lines){ if (isNullOrEmpty(lines)){ return Collections.emptySet(); } Set<String> set = new HashSet<>(); for (ShoppingCartLineCommand line : lines){ CollectionsUtil.addAllIgnoreNull(set, line.getComboIds()); } return set; } ``` 重构之后,方法的复杂度会更小,阅读性更高 ### 1.2 **addIgnoreNullOrEmpty**(Collection<T>, T) 对于以下代码: ```JAVA List<Object[]> dataList = new ArrayList<>(); for (T bean : iterable){ Object[] objectArray = toObjectArray(bean, propertyNameList); if (isNotNullOrEmpty(objectArray)){ dataList.add(objectArray); } } return dataList; ``` **可以重构成: ** ```JAVA List<Object[]> dataList = new ArrayList<>(); for (T bean : iterable){ addIgnoreNullOrEmpty(dataList, toObjectArray(bean, propertyNameList)); } return dataList; ``` 重构之后,方法的复杂度会更小,阅读性更高 ## 2.查找 方法 | Description :---- | :--------- **find**(Iterable<O>, String, V) | 找到 iterable中,第一个 propertyName属性名称值是 `propertyValue` 的对应元素. **find**(Iterable<O>, Predicate<O>) | 迭代查找匹配`predicate` 的第一个元素并返回. ### 2.1 find(Iterable<O>, String, V) 比如以下代码: ```JAVA public Boolean hasDistributionMode(CalcFreightCommand calcFreightCommand,Long shopId){ // 通过收货地址获取支持的物流方式 List<DistributionMode> distributionModeList = findDistributeMode( shopId, calcFreightCommand.getProvienceId(), calcFreightCommand.getCityId(), calcFreightCommand.getCountyId(), calcFreightCommand.getTownId()); Boolean flag = false; if (Validator.isNotNullOrEmpty(distributionModeList)){ if (null != calcFreightCommand.getDistributionModeId()){ for (DistributionMode distributionMode : distributionModeList){ if (distributionMode.getId().equals(calcFreightCommand.getDistributionModeId())){ flag = true; } } }else{ flag = true; } } return flag; } ``` 22行代码,可以重构成 ```JAVA public Boolean hasDistributionMode(CalcFreightCommand calcFreightCommand,Long shopId){ // 通过收货地址获取支持的物流方式 List<DistributionMode> distributionModeList = findDistributeMode(shopId, calcFreightCommand.getProvienceId(), calcFreightCommand.getCityId(), calcFreightCommand.getCountyId(), calcFreightCommand.getTownId()); if (isNullOrEmpty(distributionModeList)){ return false; } if (isNullOrEmpty(calcFreightCommand.getDistributionModeId())){ return true; } DistributionMode distributionMode = CollectionsUtil.find(distributionModeList, "id", calcFreightCommand.getDistributionModeId()); return null != distributionMode; } ``` 只需要14行代码,而且可阅读性更高 ### 2.2 find(Iterable<O>, Predicate<O>) 场景: 从list中查找`name是 关羽`,并且 `age等于30`的User对象 ```JAVA List<User> list = toList(// new User("张飞", 23), new User("关羽", 24), new User("刘备", 25), new User("关羽", 30)); Map<String, Object> map = new HashMap<>(); map.put("name", "关羽"); map.put("age", 30); Predicate<User> predicate = BeanPredicateUtil.equalPredicate(map); User user = CollectionsUtil.find(list, predicate); LOGGER.debug(JsonUtil.format(user)); ``` **返回:** ```JSON { "age": 30, "name": "关羽" } ``` ## 3. 定位 方法 | Description :---- | :--------- **indexOf**(List<O>, String, V) | 在list中,查找第一个属性 propertyName 值是指定值 propertyValue 对象的索引位置. **示例:** ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); CollectionsUtil.indexOf(list, "name", "张飞") = 0 CollectionsUtil.indexOf(null, "age", 24) = -1 CollectionsUtil.indexOf(new ArrayList<User>(), "age", 24) = -1 ``` **说明:** - 常用于浏览历史记录,当前的商品id是否在历史记录中第一条位置,如果是,可能就不会操作Cookie,诸如此类的操作 ## 4. 查询 方法 | Description :---- | :--------- **select**(Collection<O>, String, V...) | 循环 objectCollection,获得元素 bean的 propertyName的值,判断是否在propertyValues 数组中;如果在,将该对象存入list中返回. **select**(Collection<O>, String, Collection<V>) | 循环 objectCollection,获得元素 bean 的propertyName的值,判断是否在propertyValueList 集合中;如果在,将该对象存入list中返回. **select**(Collection<O>, Predicate<O>) | 按照指定的 Predicate,返回查询出来的集合. ### 4.1 select(Collection<O>, String, V...) 循环 `objectCollection`,获得元素 bean的 propertyName的值,判断是否在propertyValues 数组中;如果在,将该对象存入list中返回. **注意:** - 查询的结果的顺序按照原来 `objectCollection`里面的顺序,和参数 `propertyValues` 无关,如果你需要结果里面的元素按照指定的`propertyValues` 顺序排序的话,可以将结果再调用`SortUtil.sortListByFixedOrderPropertyValueArray(List, String, Object)` **示例:** ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); String[] array = { "刘备", "关羽" }; LOGGER.info(JsonUtil.format(CollectionsUtil.select(list, "name", array))); ``` **返回:** ```JSON [{ "age": 24, "name": "关羽" },{ "age": 25, "name": "刘备" }] ``` ### 4.2 select(Collection<O>, String, Collection<V>) 循环 `objectCollection`,获得元素 bean 的propertyName的值,判断是否在propertyValueList 集合中;如果在,将该对象存入list中返回. **说明:** - 查询的结果的顺序按照原来 `objectCollection`里面的顺序,和参数 `propertyValueList` 无关,如果你需要结果里面的元素按照指定的 `propertyValueList`顺序排序的话,可以将结果再调用`SortUtil.sortListByFixedOrderPropertyValueList(List, String, List)` - 和该方法正好相反的是 `selectRejected(Collection, String, Collection)` **示例:** 场景: 查询 name属性是"张飞"或者是"刘备"的 User list ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); List<String> propertyValueList = new ArrayList<>(); propertyValueList.add("张飞"); propertyValueList.add("刘备"); LOGGER.info(JsonUtil.format(CollectionsUtil.select(list, "name", propertyValueList))); ``` **返回:** ```JSON [{ "age": 23, "name": "张飞" },{ "age": 25, "name": "刘备" }] ``` **重构:** 对于以下代码: ```JAVA // 当前店铺 的物流方式Id set Set<Long> distributionModeIdSet = new HashSet<>(); for (TemeplateDistributionMode tdCmd : temeplateDistributionModeList){ distributionModeIdSet.add(tdCmd.getDistributionModeId()); } // 拿到所有的物流方式 列表 List<DistributionCommand> distributionCommandList = freigthMemoryManager.getDistributionList(); // 根据 物流方式ID 找出 支持本商铺的 DistributionCommand List<DistributionCommand> curShopDistributionCommandList = new ArrayList<>(); for (Long modeId : distributionModeIdSet){ for (DistributionCommand distributionCmd : distributionCommandList){ if (modeId.equals(distributionCmd.getDistributionModeId())){ curShopDistributionCommandList.add(distributionCmd); } } } ``` 可以重构成: ```JAVA // 当前店铺 的物流方式Id set Set<Long> distributionModeIdSet = CollectionsUtil.getPropertyValueSet(temeplateDistributionModeList, "distributionModeId"); // 拿到所有的物流方式 列表 List<DistributionCommand> distributionCommandList = freigthMemoryManager.getDistributionList(); // 根据 物流方式ID 找出 支持本商铺的 DistributionCommand List<DistributionCommand> curShopDistributionCommandList = CollectionsUtil.select(distributionCommandList, "distributionModeId", distributionModeIdSet); ``` ### 4.3 select(Collection<O>, Predicate<O>) 按照指定的 `Predicate`,返回查询出来的集合. **说明:** - 和该方法正好相反的是 selectRejected(Collection, Predicate) **示例1:** 场景: 查找等于 1的元素 ```JAVA List<Long> list = new ArrayList<>(); list.add(1L); list.add(1L); list.add(2L); list.add(3L); LOGGER.info(JsonUtil.format(CollectionsUtil.select(list, new EqualPredicate<Long>(1L)))); ``` **返回:** ```JSON [1,1] ``` **示例2:** 场景: 查找大于 10的元素 ```JAVA Comparator<Integer> comparator = ComparatorUtils.naturalComparator(); Predicate<Integer> predicate = new ComparatorPredicate<Integer>(10, comparator, Criterion.LESS); List<Integer> select = CollectionsUtil.select(toList(1, 5, 10, 30, 55, 88, 1, 12, 3), predicate); LOGGER.debug(JsonUtil.format(select, 0, 0)); ``` **返回:** ```JSON [30,55,88,12] ``` ## 5. 反查 方法 | Description :---- | :--------- **selectRejected**(Collection<O>, String, V...) | 循环 objectCollection,获得元素 bean 的 propertyName 属性值都不在 propertyValues 时候的list. **selectRejected**(Collection<O>, String, Collection<V>) | 循环 objectCollection,获得元素 bean 的 propertyName的值,判断是否不在propertyValueList 集合中;如果不在,将该对象存入list中返回. **selectRejected**(Collection<O>, Predicate<O>) | 循环 objectCollection,获得元素 bean,判断是否不匹配predicate,如果不匹配 ,将该对象存入list中返回. ### 5.1 selectRejected(Collection<O>, String, V...) 循环 `objectCollection`,获得元素 bean 的 propertyName 属性值都不在 propertyValues 时候的list. **示例:** 场景: 查询name 不是刘备 也不是张飞的 User list元素 ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); List<User> selectRejected = CollectionsUtil.selectRejected(list, "name", "刘备", "张飞"); LOGGER.info(JsonUtil.format(selectRejected)); ``` **返回:** ```JSON [{ "age": 24, "name": "关羽" }] ``` ### 5.2 selectRejected(Collection<O>, String, Collection<V>) 循环 `objectCollection`,获得元素 bean 的 propertyName的值,判断是否不在propertyValueList 集合中;如果不在,将该对象存入list中返回. **示例:** 场景: 查询 name属性是不是"张飞",也不是"刘备"的 User list ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); List<String> propertyValueList = new ArrayList<>(); propertyValueList.add("张飞"); propertyValueList.add("刘备"); LOGGER.info(JsonUtil.format(CollectionsUtil.selectRejected(list, "name", propertyValueList))); ``` **返回:** ```JSON [{ "age": 24, "name": "关羽" }] ``` ### 5.3 selectRejected(Collection<O>, Predicate<O>) 循环 objectCollection,获得元素 bean,判断是否不匹配predicate,如果不匹配 ,将该对象存入list中返回. **说明:** - 和该方法正好相反的是 select(Collection, Predicate) **示例:** 场景: 从list中查找不等于1的元素 ```JAVA List<Long> list = toList(1L, 1L, 2L, 3L); CollectionsUtil.selectRejected(list, new EqualPredicate<Long>(1L)); ``` **返回:** ```JSON 2L, 3L ``` ## 6. 提取 方法 | Description :---- | :--------- **getPropertyValueList**(Collection<O>, String) | 循环集合 objectCollection,取到对象指定的属性 propertyName的值,拼成List(ArrayList). **getPropertyValueSet**(Collection<O>, String)| 解析迭代集合 objectCollection ,取到对象指定的属性 propertyName的值,拼成Set(LinkedHashSet). **getPropertyValueMap**(Collection<O>, String, String) | 循环 objectCollection ,以 keyPropertyName属性值为key, valuePropertyName属性值为value,组成map返回. ### 6.1 getPropertyValueList(Collection<O>, String) 循环集合 `objectCollection`,取到对象指定的属性 propertyName的值,拼成List(ArrayList). **示例:** 场景: 获取user list每个元素的id属性值,组成新的list返回 ```JAVA List<User> list = toList(// new User(2L), new User(5L), new User(5L)); List<Long> resultList = CollectionsUtil.getPropertyValueList(list, "id"); LOGGER.debug(JsonUtil.format(resultList)); ``` **返回:** ```JSON [2,5,5] ``` ### 6.2 getPropertyValueSet(Collection<O>, String) 解析迭代集合 `objectCollection` ,取到对象指定的属性 propertyName的值,拼成Set(LinkedHashSet). **说明:** 返回的是 LinkedHashSet,顺序是参数 objectCollection 元素的顺序 **示例:** ```JAVA List<User> list = new ArrayList<>(); list.add(new User(2L)); list.add(new User(5L)); list.add(new User(5L)); LOGGER.info(JsonUtil.format(CollectionsUtil.getPropertyValueSet(list, "id"))); ``` **返回:** ```JSON [2,5] ``` ### 6.3 getPropertyValueMap(Collection<O>, String, String) 循环 `objectCollection` ,以 keyPropertyName属性值为key, valuePropertyName属性值为value,组成map返回. **说明:** - 返回的是 LinkedHashMap,顺序是参数 objectCollection 元素的顺序 - 如果有元素 keyPropertyName属性值相同,那么后面的值会覆盖前面的值 **示例:** ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("刘备", 25)); LOGGER.info(JsonUtil.format(CollectionsUtil.getPropertyValueMap(list, "name", "age"))); ``` **返回:** ```JSON { "张飞": 23, "关羽": 24, "刘备": 25 } ``` 如果有元素 keyPropertyName属性值相同,那么后面的值会覆盖前面的值 ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("关羽", 24)); list.add(new User("张飞", 25)); LOGGER.info(JsonUtil.format(CollectionsUtil.getPropertyValueMap(list, "name", "age"))); ``` **返回:** ```JSON { "张飞": 25, "关羽": 24, } ``` ## 7. 分组 方法 | Description :---- | :--------- **group**(Collection<O>, String)| 循环 objectCollection,以 元素的 propertyName属性值为key,相同值的元素组成list作为value,封装成map返回. **group**(Collection<O>, String, Predicate<O>) | 循环 objectCollection,找到符合条件的 includePredicate的元素,以元素的 propertyName 属性值为key,相同值的元素组成list作为value,封装成map返回. **group**(Collection<O>, Transformer<O, T>)| 循环 objectCollection,将元素使用keyTransformer转成key,相同值的元素组成list作为value,封装成map返回. **group**(Collection<O>, Predicate<O>, Transformer<O, T>) | 循环 objectCollection,找到符合条件的 includePredicate的元素,将元素使用keyTransformer转成key ,相同值的元素组成list作为value,封装成map返回. **groupOne**(Collection<O>, String) | 循环 objectCollection,以元素的 propertyName属性值为key,元素为value,封装成map返回(map只put第一个匹配的元素,后面出现相同的元素将会忽略). ### 7.1 group(Collection<O>, String) 循环 `objectCollection`,以 元素的 propertyName属性值为key,相同值的元素组成list作为value,封装成map返回. **说明:** - 返回的LinkedHashMap,key是 objectCollection中的元素对象中 propertyName的值,value是objectCollection 中的元素对象; - 顺序是 objectCollection propertyName的值顺序,如果需要排序,可自行调用 SortUtil.sortMapByKeyAsc(Map), SortUtil.sortMapByKeyDesc(Map), SortUtil.sortMapByValueAsc(Map), SortUtil.sortMapByValueDesc(Map)或者, SortUtil.sortMap(Map, java.util.Comparator) - 属性propertyName值相同的元素,组成集合 list - 如果value只需要单值的话,可以调用 groupOne(Collection, String)方法 **示例:** ```JAVA List<User> list = toList( new User("张飞", 23), new User("刘备", 25), new User("刘备", 30)); Map<String, List<User>> map = CollectionsUtil.group(list, "name"); LOGGER.debug(JsonUtil.format(map)); ``` **返回:** ```JSON { "张飞": [ { "age": 23, "name": "张飞", }], "刘备": [ { "age": 25, "name": "刘备", }, { "age": 30, "name": "刘备", } ] } ``` ### 7.2 group(Collection<O>, String, Predicate<O>) 循环 `objectCollection`,找到符合条件的 includePredicate的元素,以元素的 propertyName 属性值为key,相同值的元素组成list作为value,封装成map返回. **说明:** - 返回的LinkedHashMap,key是 objectCollection中的元素对象中 propertyName的值,value是objectCollection 中的元素对象; - 顺序是 objectCollection propertyName的值顺序,如果需要排序,可自行调用 SortUtil.sortMapByKeyAsc(Map), SortUtil.sortMapByKeyDesc(Map), SortUtil.sortMapByValueAsc(Map), SortUtil.sortMapByValueDesc(Map)或者, SortUtil.sortMap(Map, java.util.Comparator) **示例:** 场景: 将age > 20的User,按照name 进行 group ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 10)); list.add(new User("张飞", 28)); list.add(new User("刘备", 32)); list.add(new User("刘备", 30)); list.add(new User("刘备", 10)); Map<String, List<User>> map = CollectionsUtil.group(list, "name", new Predicate<User>(){ @Override public boolean evaluate(User user){ return user.getAge() > 20; } }); LOGGER.info(JsonUtil.format(map)); ``` **返回:** ```JSON { "张飞": [{ "age": 28, "name": "张飞" }], "刘备": [{ "age": 32, "name": "刘备" },{ "age": 30, "name": "刘备" } ] } ``` 当然,对于上述代码,你还可以优化成: ```JAVA Predicate<User> comparatorPredicate = BeanPredicateUtil.comparatorPredicate("age", 20, Criterion.LESS); Map<String, List<User>> map = CollectionsUtil.group(list, "name", comparatorPredicate); ``` ### 7.3 group(Collection<O>, Transformer<O, T>) 循环 `objectCollection`,将元素使用keyTransformer转成key,相同值的元素组成list作为value,封装成map返回. **说明:** - 返回的LinkedHashMap,key是 objectCollection中的元素 使用keyTransformer转换的值,value是 objectCollection中的元素对象(相同key值,组成list); - 返回的LinkedHashMap顺序,是 objectCollection 元素顺序,如果需要排序,可自行调用 `SortUtil.sortMapByKeyAsc(Map)`, SortUtil.sortMapByKeyDesc(Map), SortUtil.sortMapByValueAsc(Map), SortUtil.sortMapByValueDesc(Map)或者, SortUtil.sortMap(Map, java.util.Comparator) **示例:** 场景: 从user list中,提取user的姓名的姓为key,user组成list,返回map ```JAVA User mateng55 = new User("马腾", 55); User machao28 = new User("马超", 28); User madai27 = new User("马岱", 27); User maxiu25 = new User("马休", 25); User zhangfei28 = new User("张飞", 28); User liubei32 = new User("刘备", 32); User guanyu50 = new User("关羽", 50); User guanping32 = new User("关平", 32); User guansuo31 = new User("关索", 31); User guanxing20 = new User("关兴", 18); //************************************************************************ List<User> list = toList(mateng55, machao28, madai27, maxiu25, zhangfei28, liubei32, guanyu50, guanping32, guansuo31, guanxing20); //************************************************************************ Map<String, List<User>> map = CollectionsUtil.group(list,new Transformer<User, String>(){ @Override public String transform(User user){ //提取名字 的姓 return user.getName().substring(0, 1); } }); LOGGER.debug(JsonUtil.format(map)); ``` **返回:** ```JSON { "马":[{ "age": 55, "name": "马腾", },{ "age": 28, "name": "马超", },{ "age": 27, "name": "马岱", },{ "age": 25, "name": "马休", } ], "张": [{ "age": 28, "name": "张飞", }], "刘": [{ "age": 32, "name": "刘备", }], "关": [{ "age": 50, "name": "关羽", },{ "age": 32, "name": "关平", },{ "age": 31, "name": "关索", },{ "age": 18, "name": "关兴", } ] } ``` ### 7.4 group(Collection<O>, Predicate<O>, Transformer<O, T>) 循环 `objectCollection`,找到符合条件的 includePredicate的元素,将元素使用keyTransformer转成key ,相同值的元素组成list作为value,封装成map返回. **说明:** - 返回的LinkedHashMap,key是 objectCollection中的元素 使用keyTransformer转换的值,value是 objectCollection中的元素对象(相同key值,组成list); - 返回的LinkedHashMap顺序,是 objectCollection 元素顺序,如果需要排序,可自行调用 `SortUtil.sortMapByKeyAsc(Map)`, `SortUtil.sortMapByKeyDesc(Map)`, `SortUtil.sortMapByValueAsc(Map)`, `SortUtil.sortMapByValueDesc(Map)`或者, `SortUtil.sortMap(Map, java.util.Comparator) ` **示例:** 场景: 从user list中,提取 年龄 大于20的user,user的姓名的姓为key,user组成list,返回map ```JAVA User mateng55 = new User("马腾", 55); User machao28 = new User("马超", 28); User madai27 = new User("马岱", 27); User maxiu25 = new User("马休", 25); User zhangfei28 = new User("张飞", 28); User liubei32 = new User("刘备", 32); User guanyu50 = new User("关羽", 50); User guanping32 = new User("关平", 32); User guansuo31 = new User("关索", 31); User guanxing20 = new User("关兴", 18); //************************************************************************ List<User> list = toList(mateng55, machao28, madai27, maxiu25, zhangfei28, liubei32, guanyu50, guanping32, guansuo31, guanxing20); //************************************************************************ Predicate<User> comparatorPredicate = BeanPredicateUtil.comparatorPredicate("age", 20, Criterion.LESS); Map<String, List<User>> map = CollectionsUtil.group(list, comparatorPredicate, new Transformer<User, String>(){ @Override public String transform(User user){ //提取名字 的姓 return user.getName().substring(0, 1); } }); LOGGER.debug(JsonUtil.format(map)); ``` **返回:** ```JSON { "马":[{ "age": 55, "name": "马腾", },{ "age": 28, "name": "马超", },{ "age": 27, "name": "马岱", },{ "age": 25, "name": "马休" }], "张": [{ "age": 28, "name": "张飞" }], "刘": [{ "age": 32, "name": "刘备" }], "关": [{ "age": 50, "name": "关羽" },{ "age": 32, "name": "关平" },{ "age": 31, "name": "关索" }] } ``` ### 7.5 groupOne(Collection<O>, String) 循环 objectCollection,以元素的 propertyName属性值为key,元素为value,封装成map返回(map只put第一个匹配的元素,后面出现相同的元素将会忽略). **说明:** - 返回的LinkedHashMap,key是 objectCollection中的元素对象中 propertyName的值,value是 objectCollection中的元素对象; - 顺序是 objectCollection propertyName的值 顺序,如果需要排序,可自行调用 `SortUtil.sortMapByKeyAsc(Map)`, `SortUtil.sortMapByKeyDesc(Map)`, `SortUtil.sortMapByValueAsc(Map)`, `SortUtil.sortMapByValueDesc(Map)`或者, `SortUtil.sortMap(Map, java.util.Comparator) ` - 间接的可以做到基于某个属性值去重的效果 - 如果value需要是集合的话,可以调用 `group(Collection, String)`方法 **示例:** ```JAVA List<User> list = new ArrayList<>(); list.add(new User("张飞", 23)); list.add(new User("刘备", 25)); list.add(new User("刘备", 30)); Map<String, User> map = CollectionsUtil.groupOne(list, "name"); LOGGER.info(JsonUtil.format(map)); ``` **返回:** ```JSON { "张飞": { "age": 23, "name": "张飞" }, "刘备": { "age": 25, "name": "刘备" } } ``` ## 8.删除 方法 | Description :---- | :--------- **remove**(Collection<O>, O)| 从 objectCollection中 删除removeElement (原集合对象不变). **removeAll**(Collection<O>, Collection<O>)| 从 objectCollection中删除所有的 removeCollection (原集合对象不变). **removeDuplicate**(Collection<O>)| 去重,返回没有重复元素的新list (原集合对象不变). ### 8.1 remove(Collection<O>, O) 从 `objectCollection`中 删除removeElement (原集合对象不变). **说明:** - 返回剩余的集合 (原集合对象不变),这个方法非常有用,如果你不想修改 collection的话,不能调用 collection.remove(removeElement);. - 底层实现是调用的 ListUtils.removeAll(Collection, Collection),将不是removeElement 的元素加入到新的list返回. **示例:** ```JAVA List<String> list = new ArrayList<>(); list.add("xinge"); list.add("feilong1"); list.add("feilong2"); list.add("feilong2"); LOGGER.info(JsonUtil.format(CollectionsUtil.remove(list, "feilong2"))); ``` **返回:** ```JSON ["xinge","feilong1"] ``` 此时,原来的list不变: ```JAVA LOGGER.info(JsonUtil.format(list)); ``` **输出 : ** ```JSON ["xinge","feilong1","feilong2","feilong2"] ``` ### 8.2 removeAll(Collection<O>, Collection<O>) 从 `objectCollection`中删除所有的 `removeCollection` (原集合对象不变). 说明: - 返回剩余的集合 (原集合对象objectCollection不变),如果你不想修改 objectCollection的话,不能直接调用 collection.removeAll(remove);,这个方法非常有用. - 底层实现是调用的 `ListUtils.removeAll(Collection, Collection)`,将不是removeElement的元素加入到新的list返回. **示例:** 场景: 从list中删除 "feilong2","feilong1"元素 ```JAVA List<String> list = toList("xinge", "feilong1", "feilong2", "feilong2"); List<String> removeList = CollectionsUtil.removeAll(list, toList("feilong2", "feilong1")); ``` **返回:** ```JSON ["xinge"] ``` ### 8.3 removeDuplicate(Collection<O>) 去重,返回没有重复元素的新list (原集合对象不变). **示例:** ```JAVA List<String> list = new ArrayList<>(); list.add("feilong1"); list.add("feilong2"); list.add("feilong2"); list.add("feilong3"); LOGGER.info(JsonUtil.format(CollectionsUtil.removeDuplicate(list))); ``` 返回: ```JSON ["feilong1","feilong2","feilong3"] ``` **注意:** - 如果原 `objectCollection` 是有序的,那么返回的结果参照原 `objectCollection`元素顺序 - 原 `objectCollection`不变 ## 9.转换 方法 | Description :---- | :--------- **collect**(Iterable<O>, Transformer<? super O, ? extends T>)| 循环 inputIterable,将每个元素使用 transformer 转换成新的对象,返回新的list. **collect**(Iterator<O>, Transformer<? super O, ? extends T>)| 循环 inputIterator,将每个元素使用 transformer 转换成新的对象 返回新的list. **collect**(Iterable<I> inputBeanIterable, Class<O> outputListBeanType, String... includePropertyNames)| 循环 inputBeanIterable,将每个元素使用转换程成新的 outputListBeanType 类型对象(如有需要只copy传入的includePropertyNames属性) 返回新的list.. ### 9.1 collect(Iterable<O>, Transformer<? super O, ? extends T>) 循环 `inputIterable`,将每个元素使用 `transformer` 转换成新的对象,返回新的list. **示例:** ```JAVA List<String> list = new ArrayList<>(); list.add("xinge"); list.add("feilong1"); list.add("feilong2"); list.add("feilong2"); Transformer<String, Object> nullTransformer = TransformerUtils.nullTransformer(); List<Object> collect = CollectionsUtil.collect(list, nullTransformer); LOGGER.info(JsonUtil.format(collect, 0, 0)); ``` **返回:** ```JSON [null,null,null,null] ``` 更多的,使用这个方法来处理两个不同类型的转换: - 比如购物车功能,有游客购物车CookieShoppingCartLine以及内存购物车对象 ShoppingCartLineCommand,两个数据结构部分元素相同, - 用户登陆需要把cookie中的购物车转成内存购物车ShoppingCartLineCommand list,这时我们可以先创建ToShoppingCartLineCommandTransformer **代码示例: ** ```JAVA class ToShoppingCartLineCommandTransformer implements Transformer<CookieShoppingCartLine, ShoppingCartLineCommand>{ private static final String[] COPY_PROPERTY_NAMES = {"skuId","extentionCode","quantity","createTime","settlementState","lineGroup" }; public ShoppingCartLineCommand transform(CookieShoppingCartLine cookieShoppingCartLine){ // 将cookie中的购物车 转换为 shoppingCartLineCommand ShoppingCartLineCommand shoppingLineCommand = new ShoppingCartLineCommand(); PropertyUtil.copyProperties(shoppingLineCommand, cookieShoppingCartLine, COPY_PROPERTY_NAMES); shoppingLineCommand.setId(cookieShoppingCartLine.getId()); shoppingLineCommand.setGift(null == cookieShoppingCartLine.getIsGift() ? false : cookieShoppingCartLine.getIsGift()); return shoppingLineCommand; } } ``` 然后调用: ```JAVA public List<ShoppingCartLineCommand> load(HttpServletRequest request){ // 获取cookie中的购物车行集合 List<CookieShoppingCartLine> cookieShoppingCartLineList = getCookieShoppingCartLines(request); if (isNullOrEmpty(cookieShoppingCartLineList)){ return null; } return CollectionsUtil.collect(cookieShoppingCartLineList, new ToShoppingCartLineCommandTransformer()); } ``` ### 9.2 collect(Iterator<O>, Transformer<? super O, ? extends T>) 循环 `inputIterator`,将每个元素使用 `transformer` 转换成新的对象,返回新的list. **示例:** 场景: 一个简单的将list中的所有元素转成null ```JAVA List<String> list = toList("xinge", "feilong1", "feilong2", "feilong2"); Transformer<String, Object> nullTransformer = TransformerUtils.nullTransformer(); List<Object> collect = CollectionsUtil.collect(list.iterator(), nullTransformer); LOGGER.info(JsonUtil.format(collect, 0, 0)); ``` **返回:** ```JSON [null,null,null,null] ``` ### 9.3 collect(Iterable<I> inputBeanIterable, Class<O> outputListBeanType, String... includePropertyNames) 循环 `inputBeanIterable`,将每个元素使用转换程成新的 `outputListBeanType` 类型对象(如有需要只copy传入的 `includePropertyNames` 属性) 返回新的 list. **示例:** 已知有以下两个类 User 和 Customer ```JAVA public class User{ // The id. private Long id = 0L; //** The name. private String name = "feilong"; //** 年龄. private Integer age; //setter /getter public User(Long id, String name){ this.id = id; this.name = name; } } public class Customer{ //** The id. private long id; //* The name. private String name; //setter /getter } ``` 此时有以下的 `List<User>` 需要转换成 `List<Customer>` ```JAVA List<User> list = toList(// new User(23L, "张飞"), new User(24L, "关羽"), new User(25L, "刘备")); ``` 以前你需要如此这般写: ```JAVA List<Customer> customerList = new ArrayList<>(); for (User user : list){ Customer customer = new Customer(); customer.setId(user.getId()); customer.setName(user.getName()); customerList.add(customer); } ``` 如果属性很多,书写代码很繁琐 此时你可以这么写: ```JAVA List<Customer> customerList = CollectionsUtil.collect(list, Customer.class); ``` 一行代码搞定集合转换问题 如果你只想转换 id 属性,你可以: ```JAVA List<Customer> customerList = CollectionsUtil.collect(list, Customer.class,"id"); ``` **说明:** - outputListBeanType 需要有默认的构造函数