Graphs are powerful data structures widely used to model real-world problems like social networks, maps, and web page linking. In Java, one of the most efficient ways to implement a graph is through an adjacency list. This article provides a complete guide to building a simple graph data structure in Java, including code for adding/removing vertices and edges, and printing the graph.
1. The Vertex Class (Optional)
We begin with a Vertex
class to represent each node in the graph. It encapsulates a label and implements equals()
and hashCode()
so it works well with Java collections.
java
import java.util.Objects;
public class Vertex {
private String label;
public Vertex(String label) {
this.label = label;
}
public String getLabel() {
return label;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Vertex)) return false;
Vertex vertex = (Vertex) o;
return Objects.equals(label, vertex.label);
}
@Override
public int hashCode() {
return Objects.hash(label);
}
@Override
public String toString() {
return label;
}
}
2. Graph Class Using Adjacency List
The Graph
class maintains a map of vertices and their neighbors, allowing efficient lookups and insertions.
java
import java.util.*;
public class Graph {
private final Map<Vertex, List<Vertex>> adjVertices;
public Graph() {
this.adjVertices = new HashMap<>();
}
// Add a vertex
public void addVertex(String label) {
adjVertices.putIfAbsent(new Vertex(label), new ArrayList<>());
}
// Remove a vertex
public void removeVertex(String label) {
Vertex v = new Vertex(label);
adjVertices.values().forEach(e -> e.remove(v));
adjVertices.remove(v);
}
// Add an edge (undirected)
public void addEdge(String label1, String label2) {
Vertex v1 = new Vertex(label1);
Vertex v2 = new Vertex(label2);
adjVertices.get(v1).add(v2);
adjVertices.get(v2).add(v1);
}
// Remove an edge
public void removeEdge(String label1, String label2) {
Vertex v1 = new Vertex(label1);
Vertex v2 = new Vertex(label2);
List<Vertex> eV1 = adjVertices.get(v1);
List<Vertex> eV2 = adjVertices.get(v2);
if (eV1 != null) eV1.remove(v2);
if (eV2 != null) eV2.remove(v1);
}
// Get adjacent vertices
public List<Vertex> getAdjVertices(String label) {
return adjVertices.get(new Vertex(label));
}
// Print the graph
public void printGraph() {
for (Vertex v : adjVertices.keySet()) {
System.out.print(v + " -> ");
for (Vertex w : adjVertices.get(v)) {
System.out.print(w + " ");
}
System.out.println();
}
}
}
3. Example Usage
java
public class Main {
public static void main(String[] args) {
Graph graph = new Graph();
graph.addVertex("A");
graph.addVertex("B");
graph.addVertex("C");
graph.addVertex("D");
graph.addVertex("E");
graph.addEdge("A", "B");
graph.addEdge("A", "C");
graph.addEdge("B", "D");
graph.addEdge("C", "D");
graph.addEdge("D", "E");
graph.printGraph();
}
}
Output:
mathematica
A -> B C
B -> A D
C -> A D
D -> B C E
E -> D
4. Key Concepts Explained
FeatureDescriptionaddVertex()
Adds a new vertex if it doesn’t already exist.addEdge()
Adds an undirected edge between two vertices.removeEdge()
Removes the edge between two vertices.removeVertex()
Removes a vertex and all edges connected to it.adjVertices
A map representing the graph as an adjacency list.
5. Additional Tips
🔁 Directed Graph
To make it directed, simply remove the second line in addEdge()
that adds the reverse connection:
java
// adjVertices.get(v2).add(v1); // Remove this line
🧮 Weighted Graph
To handle weights, replace List<Vertex>
with something like Map<Vertex, Integer>
or use a wrapper class.
6. Applications of Graphs
- Social Networks (users and friendships)
- Routing and Maps
- Web Crawling (pages and links)
- Dependency Resolution
- Knowledge Graphs
Final Thoughts
This implementation provides a flexible foundation for building both simple and complex graphs. Whether you're working on a backend system, pathfinding algorithm, or interview prep, mastering graphs in Java is a critical skill.