Java集合操作:Apache Commons Collections4启示录

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

Java标准库(java.util.Collections)提供了丰富的集合操作工具,但在实际开发中,我们常常会遇到一些更复杂、更繁琐的场景,需要编写大量样板代码。

虽然随着JDK版本的升级,集合的流式操作也变的简洁。但是开发者依然习惯第三方的集合操作工具,用起来更加顺手,如GuavaHutoolCommons-collections4等。

小编习惯使用Commons-collections4CollectionUtils.isNotEmpty()来判空,却从未关注里面的其他方法。它里面的很多方法都可以和GuavaHUtool媲美,我们一起看看吧!

02 核心工具类

既然是集合工具类,自然少不了ListSetMap三大集合的操作,除此之外还有队列、包等工具:

  • CollectionUtils
  • ListUtils
  • SetUtils
  • MapUtils
  • ArrayUtils
  • BagUtils
  • IterableUtils
  • QueueUtils

还有其他的一些小的工具类,就不一一列举了。小编就介绍一些被小编遗漏的一些好用的Utils

xml 复制代码
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.4</version> 
</dependency>

2.1 ListUtils工具类

这个工具类真的是太香了,不仅可以实现集合的交集、差集、合集、并集等,还可以进行集合分割、检测等操作。

java 复制代码
@Test
void listTest() {
    List<Integer> list = List.of(1, 2, 3, 4, 5);
    // 集合分割
    List<List<Integer>> partition = ListUtils.partition(list, 2);
    System.out.println(partition);
    // [[1, 2], [3, 4], [5]]

    List<Integer> list1 = List.of(1, 2, 3);
    List<Integer> list2 = List.of(3, 4, 5);
    // 合集[去重]
    List<Integer> sum = ListUtils.sum(list1, list2);
    System.out.println(sum);
    // [1, 2, 3, 4, 5]

    // 差集
    List<Integer> subtract = ListUtils.subtract(list1, list2);
    System.out.println(subtract);
    // [1, 2]

    // 并集【不去重】
    List<Integer> union = ListUtils.union(list1, list2);
    System.out.println(union);
    // [1, 2, 3, 3, 4, 5]

    // 交集
    List<Integer> intersection = ListUtils.intersection(list1, list2);
    System.out.println(intersection);
    // [3]

    System.out.println("------------------");
    // 过滤
    List<Integer> select = ListUtils.select(list, item -> item > 2);
    System.out.println(select);
    // [3, 4, 5]
    List<Integer> list3 = ListUtils.selectRejected(list, item -> item > 2);
    System.out.println(list3);
    // [1, 2]

    // 校验集合
    List<Integer> list5 = ListUtils.predicatedList(list, item -> item > 0);
    System.out.println(list5);
    // [1, 2, 3, 4, 5]

    // 不影響原來的集合
    ListUtils.transformedList(list, input -> input + 2).forEach(System.out::println);

    // 固定集合
    List<Integer> list7 = ListUtils.fixedSizeList(list);
    System.out.println(list7);
    // [1, 2, 3, 4, 5]
    list7.add(99);
    // java.lang.UnsupportedOperationException: List is fixed size
}

里面虽然有一些可以通过JDK的流式操作,但不妨碍它的优秀。

2.2 SetUtils工具类

少不了的集合操作

java 复制代码
@Test
void SetTest() {
    // 创建
    Set<Integer> sets = SetUtils.hashSet(1,5,8,9,8);
    System.out.println(sets);
    // [1, 5, 8, 9]

    Set<Integer> set1 = Set.of(1, 2, 5);
    Set<Integer> set2 = Set.of(2, 3, 6);
    // 交集
    SetView<Integer> intersection = SetUtils.intersection(set1, set2);
    System.out.println(intersection); // [2]

    // 合集
    SetView<Integer> union = SetUtils.union(set1, set2);
    System.out.println(union);
    // [5, 2, 1, 6, 3]

    // set1与set2不同的元素
    SetView<Integer> difference = SetUtils.difference(set1, set2);
    System.out.println(difference);
    // [5, 1]

    // 有序
    Set<Integer> sets2 = SetUtils.orderedSet(sets);
    sets2.add(10);
    sets2.add(7);
    sets2.forEach(System.out::println);
    // 1、5、8、9、10、7

    // 检测
    Set<Integer> integers = SetUtils.predicatedSet(sets, item -> item > 0);
    System.out.println(integers);
    // [1, 5, 7, 8, 9, 10]
}

2.3 MapUtils工具类

MapUtils方便主要在于取值,如果Value值为Object类型,就可以直接获取指定类型的值。

java 复制代码
@Test
void MapTest() {
    Map<String, Object> map = Map.of("test1", 1, "test2", 2, "test3", 3);
    // 取值
    System.out.println(MapUtils.getString(map, "test1"));
    // 1

    // 校验
    if (MapUtils.isNotEmpty(map)) {
        // 转化
        Map<Object, String> objectStringMap = MapUtils.invertMap(map);
        System.out.println(objectStringMap);
        // {1=test1, 2=test2, 3=test3}
    }

    // 转properties
    Properties properties = MapUtils.toProperties(map);
    System.out.println(properties);

    // 空值编程空字符串
    Map<String, Object> map2 = new HashMap<>(map);
    MapUtils.safeAddToMap(map2, "test4", null);
    System.out.println(map2);
    // {test4=, test2=2, test3=3, test1=1}
}

2.4 MultiSet

MultiSet是扩展的集合类,可以存储重复的值,会自动统计个数。

java 复制代码
@Test
void mutiSetTest() {
    MultiSet<String> sets = new HashMultiSet();
    sets.add("上海");
    sets.add("北京");
    sets.add("西安");
    sets.add("上海");
    sets.add("西安");
    System.out.println(sets);
    // [上海:2, 西安:2, 北京:1]

    int sh = sets.getCount("上海");
    System.out.println(sh);
    // 2
}

2.5 MultiValuedMap

MultiValuedMap同样是扩展的Map,相同的Key,对应的值为自动变成List

java 复制代码
@Test
void multiMapTest() {
    MultiValuedMap<String, Integer> map = new HashSetValuedHashMap<>();
    map.put("test1", 1);
    map.put("test2", 2);
    map.put("test3", 3);
    map.put("test2", 5);
    System.out.println(map);
    // {test2=[5, 2], test3=[3], test1=[1]}

    List<Integer> valuesAsList = MultiMapUtils.getValuesAsList(map, "test2");
    System.out.println(valuesAsList);
    // [5, 2]
}

2.6 其他

其他工具类就不介绍了,IteratorUtilsQueueUtils等仅仅对原有的队列等做了包装,感兴趣的可以深入了解

03 小结

Apache Commons Collections4 是一个功能极其强大的工具库,如果之用了其中的一小部分功能,就显的有点浪费了。

我们在开发时,都是怎么方便怎么使用。对于不常用的工具可能也不关注,使用工具时,稍微看看工具包的其他工具,可能会发现新天地。

相关推荐
neoooo1 分钟前
Spring Boot 3 + Kafka 实战指南
java·spring boot·kafka
天天摸鱼的java工程师3 分钟前
聊聊线程池中哪几种状态,分别表示什么?8 年 Java 开发:从业务踩坑到源码拆解(附监控实战)
java·后端
杨杨杨大侠7 分钟前
第4篇:AOP切面编程 - 无侵入式日志拦截
java·后端·开源
末央&17 分钟前
【JavaEE】文件IO操作
java·服务器·java-ee
渣哥20 分钟前
面试官问我Java继承本质,我用一个故事征服了他
java
yaoxin52112333 分钟前
168. Java Lambda 表达式 - 专用比较器
java·开发语言
Dcs39 分钟前
GPT-5来了!它将如何颠覆开发者的工作方式?
java
shylyly_1 小时前
Linux->多线程3
java·linux·开发语言·阻塞队列·生产者消费者模型