• 代码技巧——Apache集合类&字符串工具包中实用的API


    本篇介绍Apache集合类&字符串工具包中实用的API,很多sonar中的NPE问题都可以用Apache工具包来解决,代码的可读性也会得到提升;

    Maven依赖

    1. <dependency>
    2. <groupId>commons-collectionsgroupId>
    3. <artifactId>commons-collections4artifactId>
    4. dependency>
    5. <dependency>
    6. <groupId>org.apache.commonsgroupId>
    7. <artifactId>commons-lang3artifactId>
    8. dependency>

    1. MapUtils

    Map判空MapUtils.isNotEmpty,API已经帮我们做了非空判断,无需自己写非空判断;

    示例:

    1. @Test
    2. public void testMapUtils() {
    3. final HashMap emptyMap = Maps.newHashMap();
    4. final HashMap nullMap = null;
    5. System.out.println(MapUtils.isNotEmpty(emptyMap));
    6. System.out.println(MapUtils.isNotEmpty(emptyMap));
    7. // MapUtils.isNotEmpty等价于下面的写法 直接使用java.util.HashMap#isEmpty可能会导致NPE
    8. System.out.println(nullMap != null && !emptyMap.isEmpty());
    9. }

    Map取值MapUtils.getIntValue之类,帮助完成Map取value时的类型转换,无需自己写XX.valueOf(xx)或类型强转;

    示例:

    1. @Test
    2. public void testMapUtils2() {
    3. final HashMap map = Maps.newHashMap();
    4. map.put("int", 123);
    5. map.put("long", 99999L);
    6. map.put("string", "hello");
    7. map.put("boolean", Boolean.TRUE);
    8. map.put("booleanInt", 0);
    9. final int anInt = MapUtils.getIntValue(map, "int", 0);
    10. // MapUtils.getIntValue等价于下面的写法 且类型强转可能抛出异常
    11. int intValue = map.get("int") == null ? 0 : (Integer) map.get("int");
    12. System.out.println(anInt); // [输出]123
    13. System.out.println(intValue); // [输出]123
    14. final boolean booleanValue = MapUtils.getBooleanValue(map, "int");
    15. final boolean booleanIntValue = MapUtils.getBooleanValue(map, "booleanInt");
    16. // 注意getBoolean的逻辑:若为Boolean型/boolean字符串则直接转换,否则判断是否数值型——不等于0返回true,等于0返回false;都不满足则返回默认的false
    17. System.out.println(map.get("int") + "的getBooleanValue的结果: " + booleanValue); // [输出]123的getBooleanValue的结果: true
    18. System.out.println(map.get("booleanInt") + "的getBooleanValue的结果: " + booleanIntValue); // [输出]0的getBooleanValue的结果: false
    19. }

    需要注意的是,类型转换中,尽管MapUtils封装了对类型转换异常的捕获以及赋值默认值,还需要注意特殊类型Boolean的取值逻辑,如果强行对数值型取boolean,会有判断非零的逻辑,见上面的例子;

    2. CollectionUtils

    集合判空CollectionUtils.isNotEmpty,最常用的就是List和Set,实际上实现了Collection接口的集合类都可以判断,包含判null和空集合;

    示例:

    1. @Test
    2. public void testCollectionUtils() {
    3. final List list = Lists.newArrayList("a","a","b","c");
    4. final Set set = Sets.newHashSet(list);
    5. final List emptyList = Collections.emptyList();
    6. System.out.println(CollectionUtils.isNotEmpty(list)); // [输出]true
    7. System.out.println(CollectionUtils.isNotEmpty(set)); // [输出]true
    8. System.out.println(CollectionUtils.isNotEmpty(emptyList)); // [输出]false
    9. }

    集合相等判断CollectionUtils.isEqualCollection,对于List或Set,判断元素集是否一致,这个方法很实用,自己少写很多代码;

    示例:

    1. @Test
    2. public void testCollectionUtils1() {
    3. final HashSet setA = Sets.newHashSet();
    4. final HashSet setA1 = Sets.newHashSet();
    5. final HashSet setB = Sets.newHashSet();
    6. setA.add("a");
    7. setA.add("b");
    8. setA.add("c");
    9. setA1.add("b");
    10. setA1.add("a");
    11. setA1.add("c");
    12. setB.add("b");
    13. setB.add("c");
    14. setB.add("d");
    15. final ArrayList listA = Lists.newArrayList("a", "b", "c");
    16. final ArrayList listA1 = Lists.newArrayList("c", "a", "b");
    17. System.out.println(JSON.toJSONString(CollectionUtils.isEqualCollection(setA, setB))); // [输出]false
    18. System.out.println(JSON.toJSONString(CollectionUtils.isEqualCollection(setA, setA1))); // [输出]true
    19. // 集合相等判断与元素顺序无关
    20. System.out.println(JSON.toJSONString(CollectionUtils.isEqualCollection(listA, listA1))); // [输出]true
    21. // 集合相等判断与元素数量有关
    22. listA1.add("a");
    23. System.out.println(JSON.toJSONString(CollectionUtils.isEqualCollection(listA, listA1))); // [输出]false
    24. // 集合相等判断可以跨类型 如List与Set
    25. System.out.println(JSON.toJSONString(CollectionUtils.isEqualCollection(listA, setA))); // [输出]true
    26. }

    是否子集判断CollectionUtils.isSubCollection,对于List或Set,判断A是否B的子集,这个方法也很实用;子集的定义:若A是B的子集,则A中每个元素的数量都小于或等于该元素在B中的数量; 还有一个方法CollectionUtils.isProperSubCollection,判断A是否B的严格子集,即在A是B的子集的基础上,要求集合A的总元素数量必须小于B集合;

    示例:

    1. @Test
    2. public void testCollectionUtils1() {
    3. final HashSet setSub = Sets.newHashSet();
    4. final HashSet setAll = Sets.newHashSet();
    5. setSub.add("a");setSub.add("b");setSub.add("c");
    6. setAll.add("a");setAll.add("b");setAll.add("c");setAll.add("d");
    7. // 子集的定义是:若A是B的子集,则A中每个元素的数量都小于等于该元素在B中的数量;
    8. System.out.println(JSON.toJSONString("是否子集:" + CollectionUtils.isSubCollection(setSub, setAll)));
    9. // 严格子集的定义是:在子集的基础上,A的元素数量要小于B;
    10. System.out.println(JSON.toJSONString("是否严格子集:" + CollectionUtils.isSubCollection(setSub, setSub)));
    11. System.out.println(JSON.toJSONString("是否严格子集:" + CollectionUtils.isSubCollection(setSub, setAll)));
    12. // 若A中某元素在B中不存在,则必不是子集
    13. setSub.add("e");
    14. System.out.println(JSON.toJSONString("是否子集:" + CollectionUtils.isSubCollection(setSub, setAll)));
    15. // 子集判断可以跨类型 如List与Set
    16. final ArrayList listSub = Lists.newArrayList("a", "b");
    17. System.out.println(JSON.toJSONString("是否子集:" + CollectionUtils.isSubCollection(listSub, setAll)));
    18. listSub.add("a");
    19. System.out.println(JSON.toJSONString("是否子集:" + CollectionUtils.isSubCollection(listSub, setAll)));
    20. }

    差集CollectionUtils.subtract,集合A相比集合B,多出来的元素;

    交集CollectionUtils.intersection,集合A和集合B的交集;

    示例:

    1. @Test
    2. public void testCollectionUtils1() {
    3. final HashSet setA = Sets.newHashSet();
    4. final HashSet setB = Sets.newHashSet();
    5. setA.add("a");
    6. setA.add("b");
    7. setA.add("c");
    8. setB.add("b");
    9. setB.add("c");
    10. setB.add("d");
    11. final ArrayList listA = Lists.newArrayList("a", "b", "c");
    12. final ArrayList listB = Lists.newArrayList("c", "a", "b", "e");
    13. // 差集-A比B多的元素
    14. System.out.println(JSON.toJSONString(CollectionUtils.subtract(setA, setB))); // [输出] ["a"]
    15. // 差集-B比A多的元素
    16. System.out.println(JSON.toJSONString(CollectionUtils.subtract(setB, setA))); // [输出] ["d"]
    17. System.out.println(JSON.toJSONString(CollectionUtils.subtract(listB, listA))); // [输出] ["e"]
    18. System.out.println(JSON.toJSONString(CollectionUtils.subtract(listA, listB))); // [输出] []
    19. // A与B的交集
    20. System.out.println(JSON.toJSONString(CollectionUtils.intersection(setB, setA))); // [输出] ["b","c"]
    21. }

    3. StringUtils

    字符串相等StringUtils.equals,含判空逻辑,避免使用 == 或 equal() 导致的NPE问题,非常实用;

    非空串判断StringUtils.isNotEmpty,null及空字符串都会判为true;

    非空串及空格判断StringUtils.isNotBlank,null及空字符串、全空格都会判为true;

    示例:

    1. @Test
    2. public void testStringUtils() {
    3. String nullStr1 = null;
    4. String nullStr2 = null;
    5. String strA = "A";
    6. String strB = "B";
    7. // 字符串等值判断 含null值判断
    8. System.out.println(StringUtils.equals(nullStr1, nullStr2)); // [输出]true
    9. System.out.println(StringUtils.equals(strA, nullStr2)); // [输出]false
    10. System.out.println(StringUtils.equals(strA, strB)); // [输出]false
    11. String emptyStr = "";
    12. String blankStr1 = " ";
    13. String blankStr2 = "\n\t";
    14. // 字符串非空串判断 空格和控制符都不算空串
    15. System.out.println(StringUtils.isNotEmpty(nullStr1)); // [输出]false
    16. System.out.println(StringUtils.isNotEmpty(emptyStr)); // [输出]false
    17. System.out.println(StringUtils.isNotEmpty(blankStr1)); // [输出]true
    18. System.out.println(StringUtils.isNotEmpty(blankStr2)); // [输出]true
    19. // 字符串非空串及空格判断 空格和控制符都满足过滤条件
    20. System.out.println(StringUtils.isNotBlank(nullStr1)); // [输出]false
    21. System.out.println(StringUtils.isNotBlank(emptyStr)); // [输出]false
    22. System.out.println(StringUtils.isNotBlank(blankStr1)); // [输出]false
    23. System.out.println(StringUtils.isNotBlank(blankStr2)); // [输出]false
    24. }

    去除字符串首尾的控制符StringUtils.trim,含判空,无需调用可能导致NPE的String#trim

    去除字符串中所有的空白符StringUtils.isNotBlank,含判空,无需调用可能导致NPE的String#replaceAll

    字符串简单反转StringUtils.reverse,含判空,将指定字符串的字符倒序输出;

    示例:

    1. @Test
    2. public void testStringUtils1() {
    3. String nullStr1 = null;
    4. String str1 = " a b \n\t c \n";
    5. String str2 = "abc \n\t efg";
    6. // 去除首尾空串和控制符
    7. System.out.println(str1);
    8. System.out.println(StringUtils.trim(str1));
    9. // 兼容null
    10. System.out.println(nullStr1);
    11. System.out.println(StringUtils.trim(nullStr1)); // 输出null,无需自己做判空逻辑
    12. /* System.out.println(nullStr1.trim()); 会产生NPE*/
    13. // 去除全部空串和控制符
    14. System.out.println(str1);
    15. System.out.println(StringUtils.deleteWhitespace(str1));
    16. // 兼容null
    17. System.out.println(nullStr1);
    18. System.out.println(StringUtils.deleteWhitespace(nullStr1)); // 输出null,无需自己做判空逻辑
    19. // 字符反转且控制符也会反转
    20. System.out.println(str2);
    21. System.out.println(StringUtils.reverse(str2));
    22. // 兼容null
    23. System.out.println(nullStr1);
    24. System.out.println(StringUtils.reverse(nullStr1)); // 输出null,无需自己做判空逻辑
    25. }

    本文仅介绍使用过的认为常用的API,Apache工具包中还有一些功能更强大的API,这里不再展开一一介绍,有兴趣可以自己去看源码学习;

  • 相关阅读:
    LeetCode·每日一题·864.获取所有钥匙的最短路径·广度优先搜索
    电力通信与泛在电力物联网技术的应用与发展-安科瑞黄安南
    【电源专题】LDO的电源抑制比(PSRR)
    char* s1 = new char[len + 1];这个星号是干啥的
    python flask服务如何注册到nacos
    基于Netty,搭建高性能IM即时通讯集群
    PAT 甲级 A1107 Social Clusters
    这一次,大模型颠覆广告行业!
    PyQt5学习系列之新项目创建并使用widget
    SubGHz, LoRaWAN, NB-IoT, 物联网
  • 原文地址:https://blog.csdn.net/minghao0508/article/details/127630069