zoukankan      html  css  js  c++  java
  • Java 中节省 90% 时间的常用的工具类

    前言

    你们有木有喜欢看代码的领导啊,我的领导就喜欢看我写的代码,有事没事就喜欢跟我探讨怎么写才最好,哈哈哈...挺好。

    今天我们就一起来看看可以节省 90% 的加班时间的第三方开源库吧,第一个介绍的必须是 Apache 下的 Commons 库。第二个是 google 开源的 Guava 库。

    Apache Commons

    Apache Commons 是一个功能非常强大、经常被使用到的库。它有 40 个左右的类库,包含了对字符串、日期、数组等的操作。

    Lang3

    Lang3 是一个处理 Java 中基本对象的包,比如用 StringUtils 类操作字符串、ArrayUtils 类操作数组、DateUtils 类可以处理日期、MutablePair 类可以返回多个字段等等。

    包结构:

    image-20210719140346416

    maven 依赖

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.11</version>
    </dependency>
    

    字符串操作

    对字符串快速操作,在 if else 的少写判空条件。

    public static void main(String[] args) {
        boolean blank = StringUtils.isBlank(" ");//注意此处是null哦  这和isEmpty不一样的
        System.out.println(blank);
    
        boolean empty = StringUtils.isEmpty(" ");//注意这里是false
        System.out.println(empty);
    
        boolean anyBlank = StringUtils.isAnyBlank("a", " ", "c");// 其中一个是不是空字符串
        System.out.println(anyBlank);
    
        boolean numeric = StringUtils.isNumeric("1");//字符串是不是全是数字组成,"." 不算数字
        System.out.println(numeric);
    
        String remove = StringUtils.remove("abcdefgh", "a");//移除字符串
        System.out.println(remove);
    }
    

    输出结果:

    true
    false
    true
    true
    bcdefgh
    
    Process finished with exit code 0
    

    日期操作

    终于可以不用 SimpleDateFormat 格式化日期了,DateUtils.iterator 可以获取一段时间。

    public static void main(String[] args) throws ParseException {
    
        Date date = DateUtils.parseDate("2021-07-15", "yyyy-MM-dd");
    
        Date date1 = DateUtils.addDays(date, 1);//加一天
        System.out.println(date1);
    
        boolean sameDay = DateUtils.isSameDay(date, new Date());//比较
        System.out.println(sameDay);
        /*
            获取一段日期
            RANGE_WEEK_SUNDAY 从周日开始获取一周日期
            RANGE_WEEK_MONDAY 从周一开始获取一周日期
            RANGE_WEEK_RELATIVE 从当前时间开始获取一周日期
            RANGE_WEEK_CENTER 以当前日期为中心获取一周日期
            RANGE_MONTH_SUNDAY 从周日开始获取一个月日期
            RANGE_MONTH_MONDAY 从周一开始获取一个月日期
            */
        Iterator<Calendar> iterator = DateUtils.iterator(date, DateUtils.RANGE_WEEK_CENTER);
        while (iterator.hasNext()) {
            Calendar next = iterator.next();
            System.out.println(DateFormatUtils.format(next, "yyyy-MM-dd"));
        }
    }
    

    输出结果:

    Fri Jul 16 00:00:00 CST 2021
    false
    2021-07-12
    2021-07-13
    2021-07-14
    2021-07-15
    2021-07-16
    2021-07-17
    2021-07-18
    
    Process finished with exit code 0
    

    返回多个字段

    有时候在一个方法中需要返回多个值的时候,经常会使用 HashMap 返回或者是 JSON 返回。Lang3 下已经帮我们提供了这样的工具类,不需要再多写 HashMap 和 JSON 了。

    public static void main(String[] args) {
    
        MutablePair<Integer, String> mutablePair = MutablePair.of(2, "这是两个值");
        System.out.println(mutablePair.getLeft() + "  " + mutablePair.getRight());
    
        MutableTriple<Integer, String, Date> mutableTriple = MutableTriple.of(2, "这是三个值", new Date());
        System.out.println(mutableTriple.getLeft() + " " + mutableTriple.getMiddle() + " " + mutableTriple.getRight());
    }
    

    输出结果:

    2  这是两个值
    2 这是三个值 Fri Jul 16 15:24:40 CST 2021
    
    Process finished with exit code 0
    

    ArrayUtils 数组操作

    ArrayUtils 是专门处理数组的类,可以让方便的处理数组而不是需要各种循环操作。

    public static void main(String[] args) {
    
        //合并数组
        String[] array1 = new String[]{"value1", "value2"};
        String[] array2 = new String[]{"value3", "value4"};
        String[] array3 = ArrayUtils.addAll(array1, array2);
        System.out.println("array3:"+ArrayUtils.toString(array3));
    
        //clone 数组
        String[] array4 = ArrayUtils.clone(array3);
        System.out.println("array4:"+ArrayUtils.toString(array4));
    
        //数组是否相同
        boolean b = EqualsBuilder.reflectionEquals(array3, array4);
        System.out.println(b);
    
        //反转数组
        ArrayUtils.reverse(array4);
        System.out.println("array4反转后:"+ArrayUtils.toString(array4));
    
        //二维数组转 map
        Map<String, String> arrayMap = (HashMap) ArrayUtils.toMap(new String[][]{
            {"key1", "value1"}, {"key2", "value2"}
        });
        for (String s : arrayMap.keySet()) {
            System.out.println(arrayMap.get(s));
        }
    }
    

    输出结果:

    array3:{value1,value2,value3,value4}
    array4:{value1,value2,value3,value4}
    true
    array4反转后:{value4,value3,value2,value1}
    value1
    value2
    
    Process finished with exit code 0
    

    EnumUtils 枚举操作

    • getEnum(Class enumClass, String enumName) 通过类返回一个枚举,可能返回空;
    • getEnumList(Class enumClass) 通过类返回一个枚举集合;
    • getEnumMap(Class enumClass) 通过类返回一个枚举map;
    • isValidEnum(Class enumClass, String enumName) 验证enumName是否在枚举中,返回true或false。
    public enum ImagesTypeEnum {
        JPG,JPEG,PNG,GIF;
    }
    
        public static void main(String[] args) {
            ImagesTypeEnum imagesTypeEnum = EnumUtils.getEnum(ImagesTypeEnum.class, "JPG");
            System.out.println("imagesTypeEnum = " + imagesTypeEnum);
            System.out.println("--------------");
            List<ImagesTypeEnum> imagesTypeEnumList = EnumUtils.getEnumList(ImagesTypeEnum.class);
            imagesTypeEnumList.stream().forEach(
                    imagesTypeEnum1 -> System.out.println("imagesTypeEnum1 = " + imagesTypeEnum1)
            );
            System.out.println("--------------");
            Map<String, ImagesTypeEnum> imagesTypeEnumMap = EnumUtils.getEnumMap(ImagesTypeEnum.class);
            imagesTypeEnumMap.forEach((k, v) -> System.out.println("key:" + k + ",value:" + v));
            System.out.println("-------------");
            boolean result = EnumUtils.isValidEnum(ImagesTypeEnum.class, "JPG");
            System.out.println("result = " + result);
            boolean result1 = EnumUtils.isValidEnum(ImagesTypeEnum.class, null);
            System.out.println("result1 = " + result1);
        }
    

    输出结果:

    imagesTypeEnum = JPG
    --------------
    imagesTypeEnum1 = JPG
    imagesTypeEnum1 = JPEG
    imagesTypeEnum1 = PNG
    imagesTypeEnum1 = GIF
    --------------
    key:JPG,value:JPG
    key:JPEG,value:JPEG
    key:PNG,value:PNG
    key:GIF,value:GIF
    -------------
    result = true
    result1 = false
    
    Process finished with exit code 0
    

    collections4 集合操作

    commons-collections4 增强了 Java 集合框架,提供了一系列简单的 API 方便操作集合。

    maven 依赖

     <dependency>  
        <groupId>org.apache.commons</groupId>  
        <artifactId>commons-collections4</artifactId>  
        <version>4.4</version>  
    </dependency> 
    

    CollectionUtils 工具类

    这是一个工具类,可以检查 null 元素不被加入集合,合并列表,过滤列表,两个列表的并集、差集、合集。有部分功能在 Java 8 中可以被 Stream API 替换。

    public static void main(String[] args) {
    
        //null 元素不能加进去
        List<String> arrayList1 = new ArrayList<>();
        arrayList1.add("a");
        CollectionUtils.addIgnoreNull(arrayList1, null);
        System.out.println(arrayList1.size());
    
        //排好序的集合,合并后还是排序的
        List<String> arrayList2 = new ArrayList<>();
        arrayList2.add("a");
        arrayList2.add("b");
    
        List<String> arrayList3 = new ArrayList<>();
        arrayList3.add("c");
        arrayList3.add("d");
        System.out.println("arrayList3:" + arrayList3);
    
        List<String> arrayList4 = CollectionUtils.collate(arrayList2, arrayList3);
        System.out.println("arrayList4:" + arrayList4);
    
        //交集
        Collection<String> strings = CollectionUtils.retainAll(arrayList4, arrayList3);
        System.out.println("arrayList3和arrayList4的交集:" + strings);
    
        //并集
        Collection<String> union = CollectionUtils.union(arrayList4, arrayList3);
        System.out.println("arrayList3和arrayList4的并集:" + union);
    
        //差集
        Collection<String> subtract = CollectionUtils.subtract(arrayList4, arrayList3);
        System.out.println("arrayList3和arrayList4的差集:" + subtract);
    
        // 过滤,只保留 b
        CollectionUtils.filter(arrayList4, s -> s.equals("b"));
        System.out.println(arrayList4);
    }
    

    输出结果:

    1
    arrayList3:[c, d]
    arrayList4:[a, b, c, d]
    arrayList3和arrayList4的交集:[c, d]
    arrayList3和arrayList4的并集:[a, b, c, d]
    arrayList3和arrayList4的差集:[a, b]
    [b]
    
    Process finished with exit code 0
    

    Bag 统计次数

    用于统计值在集合中出现的次数。

    public static void main(String[] args) {
        Bag bag = new HashBag<String>();
        bag.add("a");
        bag.add("b");
        bag.add("a");
        bag.add("c", 3);
        System.out.println(bag);
        System.out.println(bag.getCount("c"));
    }
    

    输出结果:

    [2:a,1:b,3:c]
    3
    
    Process finished with exit code 0
    

    beanutils Bean 操作

    beanutils 是通过反射机制对 JavaBean 进行操作的。比如对 Bean 进行复制、map 转对象、对象转 Map。

    maven 依赖

    <dependency>
        <groupId>commons-beanutils</groupId>
        <artifactId>commons-beanutils</artifactId>
        <version>1.9.4</version>
    </dependency>
    
    public class User {
        
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    public static void main(String[] args) throws Exception {
        User user1 = new User();
        user1.setName("李四");
        User user2 = (User) BeanUtils.cloneBean(user1);
        System.out.println(user2.getName());
    
        //User 转 map
        Map<String, String> describe = BeanUtils.describe(user1);
        System.out.println(describe);
    
        //Map 转 User
        Map<String, String> beanMap = new HashMap();
        beanMap.put("name", "张三");
        User user3 = new User();
        BeanUtils.populate(user3, beanMap);
        System.out.println(user3.getName());
    }
    

    输出结果:

    李四
    {name=李四}
    张三
    
    Process finished with exit code 0
    

    Guava

    Google 开源的一个基于 Java 扩展项目,包含了一些基本工具、集合扩展、缓存、并发工具包、字符串处理等。

    maven 依赖

    <dependency>
      <groupId>com.google.guava</groupId>
      <artifactId>guava</artifactId>
      <version>30.1.1-jre</version>
    </dependency>
    

    Map<String, List> 类型

    在java 代码中经常会遇到需要写 Map<String, List> map 的局部变量的时候。有时候业务情况还会更复杂一点。

    public static void main(String[] args) {
        //以前
        Map<String, List<String>> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        map.put("名称", list);
        System.out.println(map.get("名称"));
    
        //现在
        Multimap<String, String> multimap = ArrayListMultimap.create();
        multimap.put("名称", "张三");
        multimap.put("名称", "李四");
        System.out.println(multimap.get("名称"));
    }
    

    输出结果:

    [张三, 李四]
    [张三, 李四]
    
    Process finished with exit code 0
    

    value 不能重复的 Map

    在 Map 中 value 的值时可以重复的,Guava 可以创建一个 value 不可重复的 Map,并且 Map 和 value 可以对调。

    public static void main(String[] args) {
        //会报异常
        BiMap<String ,String> biMap = HashBiMap.create();
        biMap.put("key1", "value");
        biMap.put("key2", "value");
        System.out.println(biMap.get("key1"));
    }
    

    输出结果:

    Exception in thread "main" java.lang.IllegalArgumentException: value already present: value
    	at com.google.common.collect.HashBiMap.put(HashBiMap.java:287)
    	at com.google.common.collect.HashBiMap.put(HashBiMap.java:262)
    	at org.example.clone.Test.main(Test.java:17)
    
    Process finished with exit code 1
    
    public static void main(String[] args) {
        BiMap<String ,String> biMap = HashBiMap.create();
        biMap.put("key1", "value1");
        biMap.put("key2", "value2");
        System.out.println(biMap.get("key1"));
    
        //key-value 对调
        biMap = biMap.inverse();
        System.out.println(biMap.get("value1"));
    }
    

    输出结果:

    value1
    key1
    
    Process finished with exit code 0
    

    Guava cache

    写业务的时候肯定会使用缓存,当不想用第三方作为缓存的时候,Map 又不够强大,就可以使用 Guava 的缓存。

    缓存的并发级别

    Guava提供了设置并发级别的API,使得缓存支持并发的写入和读取。与ConcurrentHashMap类似,Guava cache的并发也是通过分离锁实现。在通常情况下,推荐将并发级别设置为服务器cpu核心数。

    CacheBuilder.newBuilder()
    		// 设置并发级别为cpu核心数,默认为4
    		.concurrencyLevel(Runtime.getRuntime().availableProcessors()) 
    		.build();
    

    缓存的初始容量设置

    我们在构建缓存时可以为缓存设置一个合理大小初始容量,由于Guava的缓存使用了分离锁的机制,扩容的代价非常昂贵。所以合理的初始容量能够减少缓存容器的扩容次数。

    CacheBuilder.newBuilder()
    		// 设置初始容量为100
    		.initialCapacity(100)
    		.build();
    

    设置最大存储

    Guava Cache可以在构建缓存对象时指定缓存所能够存储的最大记录数量。当Cache中的记录数量达到最大值后再调用put方法向其中添加对象,Guava会先从当前缓存的对象记录中选择一条删除掉,腾出空间后再将新的对象存储到Cache中。

    public static void main(String[] args) {
        Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(2).build();
        cache.put("key1", "value1");
        cache.put("key2", "value2");
        cache.put("key3", "value3");
        System.out.println(cache.getIfPresent("key1")); //key1 = null
    }
    

    输出结果:

    null
    
    Process finished with exit code 0
    

    过期时间

    expireAfterAccess() 可以设置缓存的过期时间。

    public static void main(String[] args) throws InterruptedException {
        //设置过期时间为2秒
        Cache<String, String> cache1 = CacheBuilder.newBuilder().maximumSize(2).expireAfterAccess(2, TimeUnit.SECONDS).build();
        cache1.put("key1", "value1");
        Thread.sleep(1000);
        System.out.println(cache1.getIfPresent("key1"));
        Thread.sleep(2000);
        System.out.println(cache1.getIfPresent("key1"));
    }
    

    输出结果:

    value1
    null
    
    Process finished with exit code 0
    

    LoadingCache

    使用自定义ClassLoader加载数据,置入内存中。从LoadingCache中获取数据时,若数据存在则直接返回;若数据不存在,则根据ClassLoaderload方法加载数据至内存,然后返回该数据。

    public class Test {
    
        public static void main(String[] args) throws Exception {
            System.out.println(numCache.get(1));
            Thread.sleep(1000);
            System.out.println(numCache.get(1));
            Thread.sleep(1000);
            numCache.put(1, 6);
            System.out.println(numCache.get(1));
    
        }
    
        private static LoadingCache<Integer, Integer> numCache = CacheBuilder.newBuilder().
                expireAfterWrite(5L, TimeUnit.MINUTES).
                maximumSize(5000L).
                build(new CacheLoader<Integer, Integer>() {
                    @Override
                    public Integer load(Integer key) throws Exception {
                        System.out.println("no cache");
                        return key * 5;
                    }
                });
    }
    

    输出结果:

    no cache
    5
    5
    6
    
    Process finished with exit code 0
    

    总结

    通过 Apache Commons 和 Guava 两个第三方的开源工具库,可以减少循环、ifelse 的代码。写出的代码更有健壮性并且可以在新人面前装一波。Apache Commons 和 Guava 有许许多多的工具类,这里只列出了小小的部分,可以在官网例子中查看到各种用法。

    最后

    我是一个正在被打击还在努力前进的码农。如果文章对你有帮助,记得点赞、关注哟,谢谢!

  • 相关阅读:
    2015531 网络攻防 Exp1 PC平台逆向破解(5)M
    2017-2018-1 20155331 嵌入式C语言
    20155330 《网络对抗》 Exp9 web安全基础实践
    20155330 《网络对抗》 Exp8 Web基础
    20155330 《网络对抗》 Exp7 网络欺诈防范
    20155330 《网络对抗》 Exp6 信息搜集与漏洞扫描
    20155330 《网络对抗》 Exp5 MSF基础应用
    20155330 《网络攻防》 Exp4 恶意代码分析
    20155330 《网络攻防》 Exp3 免杀原理与实践
    20155330 《网络对抗》 Exp2 后门原理与实践
  • 原文地址:https://www.cnblogs.com/jiangwang001/p/15092986.html
Copyright © 2011-2022 走看看