1. 概述
在现代软件开发中,追踪和可视化文件或内容不同版本之间的变更至关重要。无论是构建版本控制系统、协作编辑器还是代码审查工具,高效的内容比较都是核心需求。在 Java 生态中,Java Diff Utils 是实现这一功能的流行方案。
本教程将演示如何使用 Java Diff Utils 库完成多种任务,包括逐行文本比较、生成统一差异格式、应用补丁恢复内容,以及构建并排差异视图。
2. Java Diff Utils 核心优势解析
Java Diff Utils 是一个轻量级且强大的文本差异计算库,支持字符级和行级比较,并能生成标准统一差异输出。它常用于版本控制系统,通过应用补丁将数据从一个版本转换为另一个版本。该库提供了丰富的类和方法简化比较过程。
核心优势总结:
- 简洁性:提供清晰直观的 API 和静态工具方法
- 可扩展性:无缝集成 Spring Boot 服务和控制器
- 跨平台:兼容所有支持 Java 的操作系统
- 开源协议:基于 Apache License,可自由使用和修改
这些特性使 Java Diff Utils 成为 Java 应用中实现可靠文本比较功能的理想选择。
3. 快速搭建环境
在深入实战前,我们通过 Spring Initializr 创建一个简单的 Spring Boot Maven 项目。
虽然 Java Diff Utils 可在纯 Java 环境中手动管理 JAR 使用,但 Spring Boot + Maven 通过 pom.xml
自动处理依赖,显著简化了配置。这种方式不仅减少设置时间,还确保了环境间的一致性和可移植性——Maven 会自动下载、管理和解析所有依赖。
在 pom.xml
中添加 Java Diff Utils 依赖:
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.12</version>
</dependency>
配置完成后,Maven 会确保在编译和运行时提供正确版本的库。现在可以直接使用核心类如 DiffUtils
、Patch
和 UnifiedDiffUtils
。这些类都是工具类,无需显式实例化,可轻松集成到服务层、控制器或独立组件中。
4. Java Diff Utils 实战应用
本节将通过构建基础组件,演示 Java Diff Utils 在多种场景下的使用。我们将探索核心用例:内容比较、差异生成、补丁应用和并排视图构建。
4.1. 字符串列表比较
创建工具类 TextComparatorUtil
比较两个字符串列表并生成差异补丁:
class TextComparatorUtil {
public static Patch<String> compare(List<String> original, List<String> revised) {
return DiffUtils.diff(original, revised);
}
}
验证 TextComparatorUtil
能正确检测变更:
@Test
void givenDifferentLines_whenCompared_thenDetectsChanges() {
var original = List.of("A", "B", "C");
var revised = List.of("A", "B", "D");
var patch = TextComparatorUtil.compare(original, revised);
assertEquals(1, patch.getDeltas().size());
assertEquals("C", patch.getDeltas().get(0).getSource().getLines().get(0));
assertEquals("D", patch.getDeltas().get(0).getTarget().getLines().get(0));
}
4.2. 生成统一差异格式
创建 UnifiedDiffGeneratorUtil
类生成标准统一差异输出:
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);
}
}
指定原始内容、修订内容和文件名后,即可生成适用于代码审查或版本控制系统的标准差异输出。
通过 JUnit 测试验证差异生成:
@Test
void givenModifiedText_whenUnifiedDiffGenerated_thenContainsExpectedChanges() {
var original = List.of("x", "y", "z");
var revised = List.of("x", "y-modified", "z");
var diff = UnifiedDiffGeneratorUtil.generate(original, revised, "test.txt");
assertTrue(diff.stream().anyMatch(line -> line.contains("-y")));
assertTrue(diff.stream().anyMatch(line -> line.contains("+y-modified")));
}
4.3. 应用补丁
创建 PatchUtil
类生成并应用补丁更新原始内容:
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);
}
}
先计算差异,再应用补丁将原始内容转换为修订版本。
验证补丁应用效果:
@Test
void givenPatch_whenApplied_thenMatchesRevised() throws PatchFailedException {
var original = List.of("alpha", "beta", "gamma");
var revised = List.of("alpha", "beta-updated", "gamma");
var result = PatchUtil.apply(original, revised);
assertEquals(revised, result);
}
4.4. 构建并排差异视图
创建 SideBySideViewUtil
类以可读格式展示差异:
public class SideBySideViewUtil {
private static final Logger logger = Logger.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.log(Level.INFO,"Change: " + delta.getType());
logger.log(Level.INFO,"Original: " + delta.getSource().getLines());
logger.log(Level.INFO,"Revised: " + delta.getTarget().getLines());
});
}
}
该工具识别每个变更并打印变更类型及对应行,便于快速理解文本修改。⚠️ 注意:Java Diff Utils 不直接生成 HTML 视图,但暴露的源/目标行数据可用于构建自定义可视化界面。
测试并排视图功能:
@Test
void givenDifferentLists_whenDisplayCalled_thenNoExceptionThrown() {
List<String> original = List.of("line1", "line2", "line3");
List<String> revised = List.of("line1", "line2-modified", "line3", "line4");
SideBySideViewUtil.display(original, revised);
}
5. 总结
本文深入探讨了 Java Diff Utils 的核心功能。作为灵活的开源解决方案,它为 Java 应用中的文本比较提供了强大支持——从基础行级差异到统一差异生成和补丁应用,是构建版本控制或变更追踪系统的基石工具。
凭借极简配置和高度可读的输出,Java Diff Utils 是处理版本化数据、协作编辑工具或文件监控系统的开发者必备利器。
✅ 所有示例代码可在 GitHub 获取。