Common tool classes that save 90% of time in Java

preface

You have leaders who like to read the code. My leaders like to read the code I write. If you have nothing to do, they like to discuss with me how to write the best. Hahaha... Very good.

Today, let's take a look at the third-party open source library that can save 90% of overtime. The first introduction must be the Commons Library under Apache. The second is google's open source Guava library.

Apache Commons

Apache Commons is a very powerful and frequently used library. It has about 40 class libraries, including operations on strings, dates, arrays, etc.

Lang3

Lang3 is a package for processing basic objects in Java, such as string manipulation with StringUtils class, array manipulation with ArrayUtils class, date manipulation with DateUtils class, multiple fields returned with MutablePair class, etc.

Package structure:

maven dependency

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

String operation

Fast operation on strings, write less null conditions in if else.

public static void main(String[] args) {
    boolean blank = StringUtils.isBlank(" ");//Note that this is null, which is different from isEmpty
    System.out.println(blank);

    boolean empty = StringUtils.isEmpty(" ");//Note that this is false
    System.out.println(empty);

    boolean anyBlank = StringUtils.isAnyBlank("a", " ", "c");// Is one of them an empty string
    System.out.println(anyBlank);

    boolean numeric = StringUtils.isNumeric("1");//Is the string all composed of numbers, "." Not a number
    System.out.println(numeric);

    String remove = StringUtils.remove("abcdefgh", "a");//Remove string
    System.out.println(remove);
}

Output results:

true
false
true
true
bcdefgh

Process finished with exit code 0

Date operation

Finally, you can format dates without SimpleDateFormat, dateutils The iterator can get for a period of time.

public static void main(String[] args) throws ParseException {

    Date date = DateUtils.parseDate("2021-07-15", "yyyy-MM-dd");

    Date date1 = DateUtils.addDays(date, 1);//Plus one day
    System.out.println(date1);

    boolean sameDay = DateUtils.isSameDay(date, new Date());//compare
    System.out.println(sameDay);
    /*
        Get a date
        RANGE_WEEK_SUNDAY Get the day of the week from Sunday
        RANGE_WEEK_MONDAY Get the day of the week from Monday
        RANGE_WEEK_RELATIVE Get a week's date from the current time
        RANGE_WEEK_CENTER Get the date of the week centered on the current date
        RANGE_MONTH_SUNDAY Get a month's date from Sunday
        RANGE_MONTH_MONDAY Get a month's date from 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"));
    }
}

Output results:

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

Return multiple fields

Sometimes when multiple values need to be returned in a method, HashMap return or JSON return is often used. Lang3 has provided us with such a tool class. There is no need to write more HashMap and JSON.

public static void main(String[] args) {

    MutablePair<Integer, String> mutablePair = MutablePair.of(2, "These are two values");
    System.out.println(mutablePair.getLeft() + "  " + mutablePair.getRight());

    MutableTriple<Integer, String, Date> mutableTriple = MutableTriple.of(2, "These are three values", new Date());
    System.out.println(mutableTriple.getLeft() + " " + mutableTriple.getMiddle() + " " + mutableTriple.getRight());
}

Output results:

2  These are two values
2 These are three values Fri Jul 16 15:24:40 CST 2021

Process finished with exit code 0

ArrayUtils array operation

ArrayUtils is a special class for dealing with arrays, which can make it convenient to deal with arrays instead of various circular operations.

public static void main(String[] args) {

    //Merge array
    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 array
    String[] array4 = ArrayUtils.clone(array3);
    System.out.println("array4:"+ArrayUtils.toString(array4));

    //Are the arrays the same
    boolean b = EqualsBuilder.reflectionEquals(array3, array4);
    System.out.println(b);

    //Invert array
    ArrayUtils.reverse(array4);
    System.out.println("array4 After reversal:"+ArrayUtils.toString(array4));

    //2D array to 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));
    }
}

Output results:

array3:{value1,value2,value3,value4}
array4:{value1,value2,value3,value4}
true
array4 After reversal:{value4,value3,value2,value1}
value1
value2

Process finished with exit code 0

EnumUtils enumeration operation

  • getEnum(Class enumClass, String enumName) returns an enumeration through the class, possibly null;
  • getEnumList(Class enumClass) returns an enumeration set through class;
  • getEnumMap(Class enumClass) returns an enumerated map through the class;
  • isValidEnum(Class enumClass, String enumName) verifies whether enumName is in enumeration and returns true or 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);
    }

Output results:

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 collection operation

Commons collections 4 enhances the Java collection framework and provides a series of simple API s to facilitate the operation of collections.

maven dependency

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

CollectionUtils utility class

This is a tool class that can check that null elements are not added to the set, merge the list, filter the list, and the union, difference and combination of the two lists. Some functions can be replaced by Stream API in Java 8.

public static void main(String[] args) {

    //null elements cannot be added
    List<String> arrayList1 = new ArrayList<>();
    arrayList1.add("a");
    CollectionUtils.addIgnoreNull(arrayList1, null);
    System.out.println(arrayList1.size());

    //Ordered sets are sorted after merging
    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);

    //intersection
    Collection<String> strings = CollectionUtils.retainAll(arrayList4, arrayList3);
    System.out.println("arrayList3 and arrayList4 Intersection of:" + strings);

    //Union
    Collection<String> union = CollectionUtils.union(arrayList4, arrayList3);
    System.out.println("arrayList3 and arrayList4 Union of:" + union);

    //Difference set
    Collection<String> subtract = CollectionUtils.subtract(arrayList4, arrayList3);
    System.out.println("arrayList3 and arrayList4 Difference set of:" + subtract);

    // Filter, keep only b
    CollectionUtils.filter(arrayList4, s -> s.equals("b"));
    System.out.println(arrayList4);
}

Output results:

1
arrayList3: [c, d]
arrayList4:[a, b, c, d]
arrayList3 and arrayList4 Intersection of:[c, d]
arrayList3 and arrayList4 Union of:[a, b, c, d]
arrayList3 and arrayList4 Difference set of:[a, b]
[b]

Process finished with exit code 0

Bag statistics times

Used to count the number of occurrences of a value in the collection.

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"));
}

Output results:

[2:a,1:b,3:c]
3

Process finished with exit code 0

Beautils bean operation

Bean utils operates on JavaBean s through reflection mechanism. For example, copy a bean, convert a Map to an object, and convert an object to a Map.

maven dependency

<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("Li Si");
    User user2 = (User) BeanUtils.cloneBean(user1);
    System.out.println(user2.getName());

    //User to map
    Map<String, String> describe = BeanUtils.describe(user1);
    System.out.println(describe);

    //Map to User
    Map<String, String> beanMap = new HashMap();
    beanMap.put("name", "Zhang San");
    User user3 = new User();
    BeanUtils.populate(user3, beanMap);
    System.out.println(user3.getName());
}

Output results:

Li Si
{name=Li Si}
Zhang San

Process finished with exit code 0

Guava

A Java based extension project of Google open source, including some basic tools, collection extension, caching, concurrency toolkit, string processing, etc.

maven dependency

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

Map < string, list > type

In java code, you often need to write local variables of map < string, list > map. Sometimes the business situation is a little more complicated.

public static void main(String[] args) {
    //before
    Map<String, List<String>> map = new HashMap<>();
    List<String> list = new ArrayList<>();
    list.add("Zhang San");
    list.add("Li Si");
    map.put("name", list);
    System.out.println(map.get("name"));

    //Now?
    Multimap<String, String> multimap = ArrayListMultimap.create();
    multimap.put("name", "Zhang San");
    multimap.put("name", "Li Si");
    System.out.println(multimap.get("name"));
}

Output results:

[Zhang San, Li Si]
[Zhang San, Li Si]

Process finished with exit code 0

value cannot be a duplicate Map

The value of value in the Map can be repeated. Guava can create a Map whose value cannot be repeated, and the Map and value can be exchanged.

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

Output results:

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 swap
    biMap = biMap.inverse();
    System.out.println(biMap.get("value1"));
}

Output results:

value1
key1

Process finished with exit code 0

Guava cache

When writing business, you will certainly use cache. When you don't want to use a third party as cache, and Map is not powerful enough, you can use Guava's cache.

Concurrency level of cache

Guava provides an API for setting the concurrency level, so that the cache supports concurrent writes and reads. Similar to ConcurrentHashMap, the concurrency of Guava cache is also realized by separating locks. In general, it is recommended to set the concurrency level to the number of server cpu cores.

CacheBuilder.newBuilder()
		// Set the concurrency level to the number of cpu cores. The default value is 4
		.concurrencyLevel(Runtime.getRuntime().availableProcessors()) 
		.build();

Initial cache capacity setting

When we build the cache, we can set a reasonable initial capacity for the cache. Because Guava's cache uses a separate lock mechanism, the cost of capacity expansion is very expensive. Therefore, a reasonable initial capacity can reduce the expansion times of the cache container.

CacheBuilder.newBuilder()
		// Set the initial capacity to 100
		.initialCapacity(100)
		.build();

Set maximum storage

Guava Cache can specify the maximum number of records that the Cache can store when building Cache objects. When the number of records in the Cache reaches the maximum, then call the put method to add objects to it. Guava will first select and delete one of the currently cached object records, make room, and then store the new object in the 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
}

Output results:

null

Process finished with exit code 0

Expiration time

expireAfterAccess() can set the expiration time of the cache.

public static void main(String[] args) throws InterruptedException {
    //Set the expiration time to 2 seconds
    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"));
}

Output results:

value1
null

Process finished with exit code 0

LoadingCache

Use the custom ClassLoader to load data and put it into memory. When obtaining data from LoadingCache, if the data exists, it will be returned directly; If the data does not exist, load the data into memory according to the load method of ClassLoader, and then return the data.

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;
                }
            });
}

Output results:

no cache
5
5
6

Process finished with exit code 0

summary

Through the open source tool libraries of Apache Commons and Guava, the code of loops and ifelse can be reduced. The code written is more robust and can be installed in front of new people. Apache Commons and Guava have many tool classes. Only a small part is listed here. You can see various usages in the examples on the official website.

Keywords: Java Programmer

Added by Spudgun on Sun, 16 Jan 2022 09:24:41 +0200