DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Introducing Graph Concepts in Java With Eclipse JNoSQL
  • Using Java Class Extension Library for Data-Oriented Programming - Part 2
  • Using Java Class Extension Library for Data-Oriented Programming
  • Java 23: What Developers Need to Know

Trending

  • Infrastructure as Code (IaC) Beyond the Basics
  • Intro to RAG: Foundations of Retrieval Augmented Generation, Part 2
  • Operational Principles, Architecture, Benefits, and Limitations of Artificial Intelligence Large Language Models
  • Endpoint Security Controls: Designing a Secure Endpoint Architecture, Part 2
  1. DZone
  2. Coding
  3. Java
  4. Google Guava and Its Two Fantastic Libraries: Graph and Eventbus

Google Guava and Its Two Fantastic Libraries: Graph and Eventbus

The main idea behind it was to include generics introduced in JDK 1.5 into Java Collections Framework, or JCF, and enhance its capability.

By 
Reza Ganji user avatar
Reza Ganji
DZone Core CORE ·
Mar. 08, 21 · Tutorial
Likes (9)
Comment
Save
Tweet
Share
19.1K Views

Join the DZone community and get the full member experience.

Join For Free

Guava is an open-source library that developed with Google to meet the daily needs of programmers; actually, Guava prevents code duplication that may be written by programmers all around the world. In addition to eliminating boilerplate codes, Guava makes programming easier and more efficient with better performance. Personally, I think Google used Artificial Intelligence to recognize Java developer's requirements by using their daily searches. Google Guava is a Google project, mainly developed by Google's developers, but it's been open-sourced now. The main idea behind it was to include generics introduced in JDK 1.5 into Java Collections Framework, or JCF, and enhance its capability. In general, Guava consists of three major components: 

First, basic utilities to reduce manual labor to implement common methods and behaviors and sometimes boilerplate codes.

Second, a complementary component for current collection frameworks such as  Java collections framework (JCF) formerly called the Google Collections Library and apache commons-collections, actually Guava is an extension for JCF but it has many more features than apache common collections you can see a comparison between Google Guava and Apache Commons Collections here.

Third, other utilities which provide convenient and productive features such as functional programming, you can a list of some important Guava utilities in the below table.

category name description
Basic utilities Using and avoiding null null can be ambiguous, can cause confusing errors, and is sometimes just plain unpleasant, many Guava utilities reject and fail fast on nulls, rather than accepting them blindly.
Basic utilities

Preconditions Test preconditions for your methods more easily
Basic utilities

Common object methods Simplify implementing Object methods, like hashCode() and toString().

Basic utilities
Ordering Guava's powerful "fluent Comparator" class.
Collections Immutable collections for defensive programming, constant collections, and improved efficiency
Collections New collection types for use cases that the JDK collections don't address as well as they could: multisets, multimaps, tables, bidirectional maps, and more
Collections Powerful collection utilities for common operations not provided in java.util.Collections
Collections Extension utilities writing a Collection decorator? Implementing Iterator? We can make that easier
Graphs Graph a graph whose edges are anonymous entities with no identity or information of their own
Graphs ValueGraph a graph whose edges have associated non-unique values
Graphs Network a graph whose edges are unique objects
Caches Caches Local caching, done right, and supporting a wide variety of expiration behaviors
I/O I/O Simplified I/O operations, especially on whole I/O streams and files, for Java 5 and 6
Event Bus EventBus Publish-subscribe-style communication between components without requiring the components to explicitly register with one another.
reflection Reflection Guava utilities for Java's reflective capabilities


How to Add Guava to a Project

Thank god, Maven has made life easy; just add the following dependency to your project :

XML
 




x


 
1
  <dependency>
2
            <groupId>com.google.guava</groupId>
3
            <artifactId>guava</artifactId>
4
            <version>30.1-jre</version>
5
  </dependency>


Graph

A graph is a data structure consisting of nodes and edges. The nodes are sometimes also referred to as vertices and the edges are lines or arcs that connect any two nodes in the graph. Graphs are a relatively complex data structure that every programmer has encountered at least once and every programmer has to provide their own codes to manipulate and traverse it. Guava graphs come with some utility classes to make programmers convenient to work with graphs.

'Graph<Object>' is the base interface in the package:

com.google.common.graph.Graph


MutableGraph and ImmutableGraph are the two major implementations of it.

Implementations Flowchart

Create

You can build a graph with any type with singleton class named GraphBuilder:

Java
 




xxxxxxxxxx
1
10


 
1
2
   //graph of Integers
3
MutableGraph<Integer> myGraph= GraphBuilder.directed().build();
4
5
//graph of Strings
6
MutableGraph<String> myGraph= GraphBuilder.directed().build();
7
8
9
//graph of any classes 
10
MutableGraph<MyCustomClassInstance> myGraph= GraphBuilder.directed().build();



Add Nodes, Edge 

Now, you have a graph named 'myGraph.' Time to add nodes and edges to it.

First, you can add nodes and then add an edge between them:

Java
 




x




1

          
2

          
3
//add nodes 'ul','um'
4
myGraph.addNode("ul");
5
myGraph.addNode("um");
6

          
7
//add edge between 'ul','um'
8
myGraph.putEdge("ul", "um");
9

          



or directly add edges :

Java
 




x


 
1
//adds nodes 'ul','um' and then edge between them
2
myGraph.putEdge("ul", "um");



Remove Nodes, Edges

It's easy! Exactly do the opposite of the previous code:

Java
 




xxxxxxxxxx
1


 
1
 myGraph.removeNode("ul");
2
 myGraph.removeNode("um");
3

          
4
 myGraph.removeEdge("ul", "um");


Traverse Graph

com.google.common.graph.Traverser<N> is a magical class that can traverse the nodes that are reachable from a specified (set of) start node(s).

Traverser has following methods:

breadthFirst(Iterable<? extends N> startNodes) Iterable over the nodes reachable from any of the startNodes, in the order of a breadth-first traversal
breadthFirst(N startNode) Iterable over the nodes reachable from startNode, in the order of a breadth-first traversal
depthFirstPostOrder(Iterable<? extends N> startNodes) Iterable over the nodes reachable from any of the startNodes, in the order of a depth-first post-order traversal
depthFirstPostOrder(N startNode) Iterable over the nodes reachable from startNode, in the order of a depth-first post-order traversal
depthFirstPreOrder(Iterable<? extends N> startNodes) Iterable over the nodes reachable from any of the startNodes, in the order of a depth-first pre-order traversal
forGraph(SuccessorsFunction<N> graph) Creates a new traverser for the given general graph.
forTree(SuccessorsFunction<N> tree) Creates a new traverser for a directed acyclic graph that has at most one path from the start node(s) to any node reachable from the start node(s), and has no paths from any start node to any other start node, such as a tree or forest

Let's create and traverse a simple graph using Guava:

Simple Graph

Java
 




x
1
41


 
1
import com.google.common.graph.*;
2
public class GraphTest {
3
    static class Node {
4
        private final String name;
5
        public Node(String name) {this.name = name; }
6
        @Override public String toString() {return name; }
7
    }
8

          
9
    public static void main(String argv[]) {
10
        Node root = new Node("root");
11
        MutableGraph<Node> myGraph = GraphBuilder.directed().build();
12

          
13
        Node node1=new Node(" 1 ");
14
        Node node2=new Node(" 2 ");
15
        Node node3=new Node(" 3 ");
16
        Node node4=new Node(" 4 ");
17
        Node node5=new Node(" 5 ");
18

          
19

          
20

          
21

          
22
        myGraph.putEdge(root, node1);
23
        myGraph.putEdge(root, node2);
24
        myGraph.putEdge(root, node3);
25
        myGraph.putEdge(node2, node4);
26
        myGraph.putEdge(node2, node5);
27

          
28
        //Print the nodes Depth First
29
        System.out.println("==============Dept First==============");
30
        Traverser.forGraph(myGraph).depthFirstPostOrder(root)
31
                .forEach(x->System.out.println(x));
32

          
33
        //Print the nodes Bread First
34
        System.out.println("==============Breath First==============");
35
        Traverser.forGraph(myGraph).breadthFirst(root)
36
                .forEach(x->System.out.println(x));
37
    }
38

          
39

          
40
}
41
-



Plain Text
 




x


 
1
Executaion results:
2
3
==============Dept First==============
4
 1 
5
 3 
6
 5 
7
 4 
8
 2 
9
root
10
==============Breath First==============
11
root
12
 1 
13
 3 
14
 2 
15
 5 
16
 4 
17
18
Process finished with exit code 0
19



I tried to explain the concepts in a very simple and practical way, and also tried as much as possible not to get too involved in theoretical and academic topics  .but if you need more information and more theoretical concepts you can find them here.

Eventbus

An Eventbus is a mechanism that allows different components to communicate with each other without knowing about each other. A component can send an Event to the Eventbus without knowing who will pick it up or how many others will pick it up. Components can also listen to Events on an Eventbus, without knowing who sent the Events. That way, components can communicate without depending on each other. Also, it is very easy to substitute a component. As long as the new component understands the Events that are being sent and received, the other components will never know.

http://www.rribbit.org/eventbus.html

Publisher > Subscriber Flowchart

for using Eventbus, first of all, for registering listeners and posting events you need a Bus:

Java
 




x


 
1
EventBus eventBus=new EventBus();



or every publish-subscribe system, Listeners are a must. Listeners can be created easily with the following codes:

Java
 




x


 
1
public class MyEventListener{
2
        private static int numberEvents;
3
        private static List<String> eventsList=new ArrayList<>();
4

          
5
        @Subscribe
6
        public void myEvent(String event) {
7
            System.out.println(event);
8
            numberEvents++;
9
 }



As you can see, the handler method has annotated with @Subscribe; now Listener should be added to the Eventbus and posting event. Here is a simple example:

Java
 




xxxxxxxxxx
1
32


 
1
import com.google.common.eventbus.EventBus;
2
import com.google.common.eventbus.Subscribe;
3
import org.junit.jupiter.api.Test;
4

          
5
import static org.junit.jupiter.api.Assertions.assertEquals;
6

          
7
public class EventBusTest {
8

          
9
     class EventListener{
10
        private  int numberEvents;
11

          
12
        @Subscribe
13
        public void myEvent(String event) {
14
            System.out.println(event);
15
            numberEvents++;
16
        }
17
        public  int getNumberEvents(){
18
            return  numberEvents;
19
        }
20
    }
21

          
22
@Test
23
    public void testEventBusSimpleTest(){
24
        EventBus eventBus=new EventBus();
25
        EventListener listener = new EventListener();
26
        eventBus.register(listener);
27
        eventBus.post("event1");
28
        eventBus.post("event2");
29
        assertEquals(2, listener.getNumberEvents());
30
}
31

          
32
}



OK! everything looks great. but this code was very simple. Let's solve a real-world problem: take a look at a sample from hackernoon. In this example, we would demonstrate how to use an Eventbus for simulating the payment process:

Simulated Payment Process Diagram


in this example we have two listeners, PaymentService and RecipieSender that are responsible for the transaction and sending recipes to Buyer and Seller:

Java
 




xxxxxxxxxx
1
102


 
1
import com.google.common.eventbus.AsyncEventBus;
2
import com.google.common.eventbus.EventBus;
3
import com.google.common.eventbus.Subscribe;
4
import org.junit.jupiter.api.Test;
5

          
6
import java.util.concurrent.Executors;
7

          
8
public class PaymentService {
9

          
10
    static class EventBusFactory {
11

          
12
        //create an asynch bus in new Thread
13
        private static EventBus eventBus = new AsyncEventBus(Executors.newCachedThreadPool());
14

          
15
        public static EventBus getEventBus() {
16
            return eventBus;
17
        }
18
    }
19

          
20
    class Transaction {
21
        private String transactionName;
22
        private double amount = 0.0;
23

          
24
        public Transaction(String transactionName, Double amount) {
25
            this.transactionName = transactionName;
26
            this.amount = amount;
27
        }
28

          
29
        public String getTransactionName() {
30
            return transactionName;
31
        }
32

          
33
        public double getAmount() {
34
            return amount;
35
        }
36

          
37
        @Override
38
        public String toString() {
39
            return "[transaction with name " + transactionName + " and amount " + amount + "]";
40
        }
41
    }
42

          
43
    class Recipie {
44
        private String message;
45

          
46
        public Recipie(String message) {
47
            this.message = message;
48
        }
49

          
50
        public String getMessage() {
51
            return message;
52
        }
53

          
54
        @Override
55
        public String toString() {
56
            return message;
57
        }
58
    }
59

          
60

          
61
    //listener
62
    class paymentService {
63

          
64
        @Subscribe
65
        private void debitBuyer(Transaction transaction) {
66
            System.out.println("going to debit buyer for following transaction : " + transaction);
67
        }
68

          
69
        @Subscribe
70
        private void creditSeller(Transaction transaction) {
71
            System.out.println("going to credit seller for following transaction : " + transaction);
72
        }
73
    }
74

          
75
    //listener
76
    class RecieptSender {
77
        @Subscribe
78
        public void sendRecieptToCustomer(Recipie recipie) {
79
            System.out.println("Reciept sent to Customer :" + recipie.message);
80
        }
81

          
82
        @Subscribe
83
        public void sendRecieptToSeller(Recipie recipie) {
84

          
85
            System.out.println("Reciept sent to Seller " + recipie.message);
86
        }
87
    }
88

          
89
    @Test
90
    public void testPayment() {
91

          
92
        //registering listeners
93
        EventBusFactory.getEventBus().register(new paymentService());
94
        EventBusFactory.getEventBus().register(new RecieptSender());
95
        //doing payment proccess
96
        EventBusFactory.getEventBus().post(new Transaction("Buy a ticket", 100D));
97
        //sending message
98
        EventBusFactory.getEventBus().post(new Recipie(" Successful transaction"));
99

          
100

          
101
    }
102
}


Plain Text
 




x


 
1
going to debit buyer for following transaction : [transaction with name Buy a ticket and amount 100.0]
2
going to credit seller for following transaction : [transaction with name Buy a ticket and amount 100.0]
3
Reciept sent to Customer : Successful transaction
4
Reciept sent to Seller  Successful transaction
5

          
6

          



So, What Is Next?!

Guava EventBus has amazing integration with Apache Camel you can read more about it here.

Google Guava Graph (Unix) Google (verb) Java (programming language) Library

Opinions expressed by DZone contributors are their own.

Related

  • Introducing Graph Concepts in Java With Eclipse JNoSQL
  • Using Java Class Extension Library for Data-Oriented Programming - Part 2
  • Using Java Class Extension Library for Data-Oriented Programming
  • Java 23: What Developers Need to Know

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!