Guava core packages

Research Direction:

  1. Guava cache usage (loading cache mode), problems in use, Guava hit ratio monitoring, etc.
  2. Gson use, performance analysis
  3. And the advantages and disadvantages of using the package,
  4. Lambda expressions and so on,

Guava is what

1. Google’s set of open source Java core libraries (similar to Core Java)

2. Collect (universal collection and collection tool

3. * graph (related API)

4. Functional types

5. * Memory cache

6. Util.concurrent

7. IO (Java IO utility classes and utility methods)

8. Hash (hash functions and related structures) provides more complex hash methods than object.hashCode (), providing Bloom filters.

9. Primitives (Static tools for Java)

10. Reflection (Java Reflection Utility class)

11. Base (basic utility classes and interfaces)

Component communication is based on a publish-subscribe pattern, but does not need to be explicitly registered in the delegate object. # comb

13. Annotations (generic @beta)

14. math

15. net

  • Com.google.com mon. Annotations: ordinary annotation types.

  • Com.google.mon. base: Basic utility class library and interface.

  • Com.google.mon. Cache: Caching toolkit, a very simple and powerful in-JVM cache.

  • Com.google.com mon. Collect: with a collection of generic interface extension and implementation, and tools, here you will find a collection of a lot of fun.

  • Com.google.com mon. Eventbus: publish-subscribe style event bus.

  • Com.google.com mon.hash: hash toolkit.

  • Com.google.com Mon. IO: I/O toolkit.

  • Com.google.com mon. Math: Toolkit for primitive arithmetic types and supernumerals.

  • Com.google.common.net: Network toolkit.

  • Com.google.com mon. Primitives: eight primitive types and unsigned types of static toolkit.

  • Com.google.com mon. Reflect: reflect toolkit.

  • Com.google.com mon. Util. Concurrent: multi-threaded kit.

Guava features:

As an open source JAVA library developed by Google, I think there are several reasons why it is so popular

1. Developers can be provided with convenient functions outside the JDK, so that developers can easily use some Utility functions that previously required their own handwriting

2. You can force (yes, force) developers to get rid of bad programming habits that may be the result of language flaws in JAVA itself

3. Enable developers to improve their application model and architecture. This can be seen in functions such as EventBus, Filter, and Ordering of Guava.

Guava Optional

For example, if a Map’s get method returns NULL, you don’t know whether the Map has no key or whether it has a key, but the value corresponding to the key is NULL.

Optional possible = Optional.of(5);

possible.isPresent(); // returns true

possible.get(); // returns 5

The Optional Object uses a non-null Object instead of NULL. The isPresent method is used to determine if the Object is NULL.

Defensive programming

The Preconditions class in Guava is used to check that the parameters of a method are correct by making certain assertions about the parameters at the beginning of the method, and if the assertions fail, an exception is thrown, resulting in a fast failure.

Guava’s preconditions have several advantages:

Collection classes

1. Creation of collections

List<String> List = lists.newarrayList (); Set<String> set = Sets.newHashSet(); Map<String, String> map = Maps.newHashMap(); // ImmutableList<String> iList = ImmutableList. Of ("a", "b", "c"); ImmutableSet<String> iSet = ImmutableSet.of("e1", "e2"); ImmutableMap<String, String> iMap = ImmutableMap.of("k1", "v1", "k2", "v2");Copy the code

Collection tool class

Why use immutable collections

Immutable objects have many advantages, including:

Immutable forms are safe when objects are called by untrusted libraries; When an immutable object is called by multiple threads, there is no race condition problem. Immutable sets do not need to consider changes, thus saving time and space. All immutable sets have better memory utilization (analysis and test details) than their mutable forms; Immutable objects are safe to use as constants because they are fixed.

Immutable collections can be created in several ways:

• copyOf methods, such as immutableset.copyof (set); • of methods, such as ImmutableSet. Of (” a “, “b”, “c”) or ImmutableMap. Of (” a “, 1, “b”, 2); • Builder tool, Public static final ImmutableSet GOOGLE_COLORS = immutableset.builder ().addall (WEBSAFE_COLORS).add(new Color(0, 191, 255)) .build();

Associate mutable sets with immutable sets

Guava. Dev/releases/sn… Open API

Mutable set interface

Belong toJDKOr * * * * Guava

Immutable version

Collection

JDK

ImmutableCollection

List

JDK

ImmutableList

Set

JDK

ImmutableSet

SortedSet/NavigableSet

JDK

ImmutableSortedSet

Map

JDK

ImmutableMap

SortedMap

JDK

ImmutableSortedMap

Multiset

Guava

ImmutableMultiset

SortedMultiset

Guava

ImmutableSortedMultiset

Multimap

Guava

ImmutableMultimap

ListMultimap

Guava

ImmutableListMultimap

SetMultimap

Guava

ImmutableSetMultimap

BiMap

Guava

ImmutableBiMap

ClassToInstanceMap

Guava

ImmutableClassToInstanceMap

Table

Guava

ImmutableTable

guava cache

There are two ways to create a cache:

// Cache 2 implementations: 1. CacheLoader implementation

LoadingCache<String,String> cahceBuilder=CacheBuilder

.newBuilder()

.build(``new CacheLoader<String, String>(){

@Override

public String load(String key) throws Exception {

String strProValue=``"hello "``+key+``"!" ` `;

return strProValue;

}

});

cahceBuilder.put(``"begin"``, "code"``);

System.out.println(cahceBuilder.get(``"begin"``)); //code

//2. Cache callback implementation

Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(``1000``).build();

String resultVal = cache.get(``"code"``, new Callable<String>() {

public String call() {

String strProValue=``"begin "``+``"code"``+``"!" ` `;

return strProValue;

}

});

System.out.println(``"value : " + resultVal); //value : begin code!

Cache recovery

Size -based Eviction

Timed Eviction

CacheBuilder provides two methods of scheduled reclamation: • expireAfterAccess(Long, TimeUnit) : The cache item is reclaimed if it has not been read/written for a given period of time. Note that this cache is reclaimed in the same order as the size based reclamation. • expireAfterWrite(Long, TimeUnit) : The cache entry is reclaimed if it has not been written (created or overwritten) within a given period of time. This is desirable if it is considered that the cached data always becomes stale and unavailable after a fixed time.

Guava Cache can set the Cache to allow garbage collection by using weak referenced keys, or weak referenced values, or soft referenced values.

Explicitly clear the cache

At any time, you can explicitly clear cached items instead of waiting for them to be reclaim: • Individual clear: cache.invalidate (key) • Batch clear: cache.invalidateAll (keys) • Clear all cached items: Cache.invalidateAll()

Remove listener

Through CacheBuilder. RemovalListener (removalListener), you can declare a listener, to cache entries have been removed when doing some additional operations. When a cache item is removed, the RemovalListener gets the RemovalNotification, which contains the RemovalCause, key, and value.

By default, the listener method is invoked synchronously when the cache is removed. Because the maintenance of the cache and the response to the request are often simultaneous, the costly listener method slows down the normal cache request in synchronous mode. In this case, you can use RemovalListeners. Asynchronous (RemovalListener, Executor) the decoration of the listeners for asynchronous operations.

#1 was removed, cause is EXPIRED

Cache statistics

Cachebuilder-recordstats () is used to enable Guava Cache statistics. With statistics enabled, the cache.stats () method returns a C acheStats object to provide the following statistics: • hitRate() : Cache hit ratio; • averageLoadPenalty() : Average time for loading the new value, in nanoseconds; • evictionCount() : Total number of cache items reclaimed, excluding explicit clearances.

CacheStats{hitCount=1, missCount=2, loadSuccessCount=1, loadExceptionCount=1, totalLoadTime=312716967, evictionCount=2}

Functional types

Notes:

  1. Jdk8 introduces lambda expressions in the definition and use of functional interfaces due to Guava

2. Excessive use of functional programming in Guava leads to lengthy, confusing, unreadable, and inefficient code. This is by far the easiest (and most frequently) abused part.

Guava provides two basic functional interfaces: • Function

, which declares A single method B apply(A input). Function objects are generally expected to be referenced transparently — with no side effects — and the “equality” semantics in reference transparency are consistent with equals, Eq uals(function.apply(a).eq uals(function.apply(b)). • Predicate, which declares a single method, Boolean apply(T input). Predicate objects are also expected to have no side effect functions, and the “equality” semantics are consistent with equals.
,>

Compare this to Java8 functional interfaces

Concurrent programming

Abstracts concurrency from the JDK, providing a callable Future. The corresponding package: com.google.com mon. Util. Concurrent

ListenableFuture allows you to register callbacks to be called when the computation (multi-threaded execution) has completed, or to be executed immediately after the computation (multi-threaded execution) has completed. This simple improvement makes it possible to support significantly more operations that the Future in JDK Concurrent does not support.

Event Bus – Publish subscribe mechanism

Provides a very loose way to publish and subscribe, provides both synchronous and asynchronous subscribers to execute, the corresponding package: com.google.com mon. The eventbus

Sorting steps: See demo for details

1.1. Create events

The EventBus class is a message publishing and subscription class in Guava. Subscribers register and subscribe to events through EventBus. Publishers send events to EventBus, and EventBus informs time subscribers of the sequence of events. Event handlers must process events quickly, or they may pile up.

Create listener

Listening classes, or subscription classes

1.3 subscribe to events – Support asynchronous execution

Call the Register method on EventBus to complete the registration.

1.4 Publish events

Call the eventBus. post method to send an event, and EventBus in turn calls all subscribers whose receiving type is the sending event type.

Gson API and performance comparison

Commonly used API:

String json = gson.toJson(Arrays.asList(jack1, jack2)); final String json=gson.toJson(new Person[]{jack1,jack2}); final Person []jacks=gson.fromJson(json,Person[].class); The official document: https://github.com/google/gson/blob/master/UserGuide.mdCopy the code

Json parsing performance comparison based on JMH benchmark

Json deserialization:

Jdk8 and Guava simple comparison – selection

For functional programming, JDK8 is better than Guava

My.oschina.net/sunhaojava/…

type

The selection

note

The cache

guava caffeine

Collection class operation

guava

Functional programming

jdk8

JDK8 lambda expressions simplify the writing of functional interfaces

Json parsing

Gson or fastjson

See GSON for advantages, disadvantages and application scenarios

Exception handling

guava Preconditions

Throws Exception

Multiple exceptions can be handled by a single catchCopy the code

Or continue to throw up the exception

Caffeine

SpringFramework5.0 (SpringBoot2.0) dropped Google’s GuavaCache in favor of Caffeine

GuavaCache is different from Caffeine

  1. In terms of elimination algorithms, GuavaCache uses ** “LRU” algorithm, while Caffeine uses “Window TinyLFU” algorithm. This is the biggest and fundamental difference between the two.

  2. For immediate invalidation, Guava converts immediate invalidation (e.g., expireAfterAccess(0) and expireAfterWrite(0)) to setting the maximum Size to 0. This would cause the reason for removing the reminder to be SIZE rather than EXPIRED. Caffiene was able to correctly identify the causes of this culling.

  3. Instead of reminding, Guava triggers the deletion listener whenever the data is replaced, for whatever reason. Caffiene does not trigger listeners if the substituted value is exactly the same as the reference to the previous value.

  4. In terms of asyncialization, many of Caffiene’s tasks (default: ForkJoinPool.commonPool()) are done by thread pools, such as removing listeners, refreshing mechanisms, maintenance, etc.

Caffeine’s API is 90% similar to Guava’s.

Performance analysis:

Caffeine Cache provides three Cache filling strategies: manual, synchronous, and asynchronous loading.

1. Manually load the file

Specify a synchronous function each time you get a key, and call it to generate a value if the key does not exist.

2. Synchronize the load

To construct a Cache, the build method is passed a CacheLoader implementation class. Implement the load method to load the value through the key.

3. Asynchronous loading

AsyncLoadingCache is inherited from LoadingCache. Asynchronous loading uses an Executor to call a method and return a CompletableFuture. Asynchronous load caching uses a responsive programming model.

Expiration policy:

The expiration mechanism of Caffeine is declared when the Cache is constructed. There are several main types:

  1. ExpireAfterWrite: indicates how long it has been since the last write.

  2. ExpireAfterAccess: how long since the last access (write or read) has expired

  3. ExpireAfter: User-defined expiration policy;

    // Exit based on different expiration policies

    LoadingCache<String, Object> cache2 = Caffeine.newBuilder()

    .expireAfter(``new Expiry<String, Object>() {

    @Override

    public long expireAfterCreate(String key, Object value, long currentTime) {

    return TimeUnit.SECONDS.toNanos(seconds);

    }

    @Override

    public long expireAfterUpdate(``@Nonnull String s, @Nonnull Object o, long l, long l1) {

    return 0``;

    }

    @Override

    public long expireAfterRead(``@Nonnull String s, @Nonnull Object o, long l, long l1) {

    return 0``;

    }

    }).build(key -> function(key));

The refresh mechanism

RefreshAfterWrite (10, timeunit.seconds) specifies the refresh period by refreshAfterWrite(10, timeunit.seconds) :

  1. 2. The cache must be read once to update the local cache with the V2 version value.
  2. Application scenario: The old value is used by default before the new value is updated.

It should be noted that Caffeine’s refresh mechanism is ** “passive.” For example, let’s say we say refresh every 10 seconds. We access and retrieve the value v1 at time T, and at T+5 seconds, the value in the database has been updated to v2. But at T+12 seconds, which is 10 seconds later, we get “still v1” ** from the local cache through Caffeine, not v2. During this fetching process, Caffeine detects that 10 seconds have passed and loads V2 into the local cache until it is retrieved on the next fetching. The refreshIfNeeded method is called when afterRead is called in the get method to determine if the data needs to be refreshed. This means that if the data in the local cache is not read, the data in the local cache will always be old, regardless of the refresh interval!

RefreshAfterWrite is not created or overwritten in the specified time. If you access the cache again after the specified time, you will refresh the cache, and always return the old value before the new value arrives

  • Expire = expire; expire = expire; expire = expire; expire = expire; expire = expire; In the case of refresh, the key will not be removed after the specified time, and the next access will trigger a refresh. If the new value does not return, the old value will be returned

References:

Juejin. Cn/post / 684490…

Blog.csdn.net/a953713428/…