Master Text Diff in Java with Diff Utils: Real‑World Spring Boot Examples
This article introduces the Java Diff Utils library, explains its core features such as computing differences, applying patches, and generating unified diffs, and provides step‑by‑step Spring Boot 3 examples—including dependency setup, string list comparison, patch generation, application, side‑by‑side view creation, and HTML rendering—for efficient text version control.
Introduction
In software development, comparing code and text versions is a common need. Traditional methods are inefficient, so the Java Diff Utils library offers a powerful solution for Java developers.
Key Features
Compute differences between two texts
Handle any type that implements hashCode() and equals() Apply and revert patches
Parse unified diff format
Generate readable diff output
Build inline diffs
Algorithms: Myers standard algorithm, space‑optimized Myers, HistogramDiff (via JGit)
Practical Examples
1. Add Dependency
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.16</version>
</dependency>2. Compare String Lists
Create a utility class to compare two lists and obtain a Patch.
public class TextComparatorUtil {
public static Patch<String> compare(List<String> original, List<String> revised) {
return DiffUtils.diff(original, revised);
}
}Example usage:
var original = List.of("A", "B", "C");
var revised = List.of("A", "B", "D");
var patch = TextComparatorUtil.compare(original, revised);
System.err.printf("差异总数: %s%n", patch.getDeltas().size());
patch.getDeltas().forEach(delta -> {
delta.getSource().getLines().forEach(System.out::println);
System.err.println("=======================");
delta.getTarget().getLines().forEach(System.out::println);
});Output:
差异总数: 1
C
=======================
D3. Generate Unified Diff
public class UnifiedDiffGeneratorUtil {
public static List<String> generate(List<String> original, List<String> revised, String fileName) {
var patch = DiffUtils.diff(original, revised);
return UnifiedDiffUtils.generateUnifiedDiff(fileName, fileName + ".new", original, patch, 3);
}
}Example:
var original = List.of("x", "y", "z");
var revised = List.of("x", "y-modified", "z");
var diff = UnifiedDiffGeneratorUtil.generate(original, revised, "test.txt");
diff.forEach(System.out::println);Result:
--- test.txt
+++ test.txt.new
@@ -1,3 +1,3 @@
x
-y
+y-modified
z4. Apply Patch
public class PatchUtil {
public static List<String> apply(List<String> original, List<String> revised) throws PatchFailedException {
var patch = DiffUtils.diff(original, revised);
return DiffUtils.patch(original, patch);
}
}Usage:
var original = List.of("alpha", "beta", "gamma");
var revised = List.of("alpha", "beta-updated", "gamma");
var result = PatchUtil.apply(original, revised);
result.forEach(System.out::println);Output:
alpha
beta-updated
gamma5. Side‑by‑Side View
public class SideBySideViewUtil {
private static final Logger logger = LoggerFactory.getLogger(SideBySideViewUtil.class.getName());
public static void display(List<String> original, List<String> revised) {
var patch = DiffUtils.diff(original, revised);
patch.getDeltas().forEach(delta -> {
logger.info("Change: {}", delta.getType());
logger.info("Original: {}", delta.getSource().getLines());
logger.info("Revised: {}", delta.getTarget().getLines());
});
}
}Example call:
List<String> original = List.of("line1", "line2", "line3");
List<String> revised = List.of("line1", "line2-modified", "line3", "line4");
SideBySideViewUtil.display(original, revised);Sample log output:
SideBySideViewUtil Line: 16 - Change: CHANGE
SideBySideViewUtil Line: 17 - Original: [line2]
SideBySideViewUtil Line: 18 - Revised: [line2-modified]
SideBySideViewUtil Line: 16 - Change: INSERT
SideBySideViewUtil Line: 17 - Original: []
SideBySideViewUtil Line: 18 - Revised: [line4]HTML Rendering Template
The article also provides a simple HTML template with CSS and JavaScript to render original and revised texts side by side, using the diff data generated by the library.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
