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.