首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java Diff Utils 简介指南-跟踪和可视化文件或内容不同版本之间的变化

Java Diff Utils 简介指南-跟踪和可视化文件或内容不同版本之间的变化

作者头像
崔认知
发布2026-03-16 21:21:41
发布2026-03-16 21:21:41
1060
举报
文章被收录于专栏:nobodynobody

翻译:https://www.baeldung.com/java-diff-utils-intro

1. 概述

在现代软件开发中,跟踪和可视化文件或内容不同版本之间的变化至关重要。无论是构建版本控制系统、协作编辑器还是代码审查工具,高效地比较内容都是必不可少的。在 Java 中实现这一目标的流行方式之一是使用 Java Diff Utils(https://java-diff-utils.github.io/java-diff-utils/)。

本教程演示如何使用 Java Diff Utils 库执行各种任务,包括逐行比较文本内容、生成统一差异(unified diffs)、应用补丁以恢复或修改内容,以及构建并排差异视图。

2. 理解 Java Diff Utils 及其主要优点

Java Diff Utils 是一个轻量级且功能强大的库,用于计算文本数据之间的差异。它支持字符级和行级比较,并能生成统一差异输出。

它常用于版本控制系统中,并可通过补丁将某一版本的数据转换为另一版本。该工具提供了多种类和方法,简化了比较过程。

以下是 Java Diff Utils 的主要优点

  • 简洁性:提供干净、直观的 API,并包含静态工具方法
  • 可扩展性:可轻松与 Spring Boot 服务和控制器集成
  • 跨平台:兼容任何支持 Java 的操作系统
  • 开源:在 Apache 许可证下可免费使用和修改

这些能力使 Java Diff Utils 成为在 Java 应用中实现可靠文本比较功能的理想选择。

3. 设置 Diff Utils

在深入使用之前,我们先通过 Spring Initializr 创建一个简单的 Spring Boot Maven 项目。

虽然可以通过手动管理 JAR 和类路径的方式在纯 Java 中使用 Java Diff Utils,但使用 Spring Boot 和 Maven 可以通过 pom.xml 自动处理所有依赖关系。这种方式不仅减少了设置时间,还确保了跨环境的一致性和可移植性。Maven 会自动下载、管理并解析所有所需的构件。

首先,在 pom.xml 中添加 Java Diff Utils 依赖:

代码语言:javascript
复制
<dependency>
    <groupId>io.github.java-diff-utils</groupId>
    <artifactId>java-diff-utils</artifactId>
    <version>4.12</version>
</dependency>

完成此设置后,Maven 会确保在编译和运行时都能使用正确版本的 Java Diff Utils。

现在,我们可以直接使用核心类,如 DiffUtilsPatchUnifiedDiffUtils。这些类都是基于工具方法设计的,无需显式创建实例。这种设计使其可以轻松集成到服务类、控制器层或独立的 Java 组件中。

4. 在 Java 中使用 Diff Utils

本节将逐步构建一些基础组件,学习如何在不同场景下使用 Java Diff Utils 库。我们将探索几种核心用例,并查看在 Java 应用中实现内容比较、生成差异、应用补丁以及并排查看变化的实现方式。

让我们进一步探索这些核心用例及其实现。

4.1 比较字符串列表

我们创建一个名为 TextComparatorUtil 的工具类,用于比较两个字符串列表,并生成一个表示其差异的补丁。该工具类简化了识别文本版本之间变化的过程:

代码语言:javascript
复制
class TextComparatorUtil {
    public static Patch<String> compare(List<String> original, List<String> revised) {
        return DiffUtils.diff(original, revised);
    }
}

验证 TextComparatorUtil 是否能正确检测并报告两个字符串列表之间的变化:

代码语言:javascript
复制
@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 生成统一差异(Unified Diffs)

接下来,我们创建一个类 UnifiedDiffGeneratorUtil,用于生成两个字符串列表之间的统一差异,以标准补丁格式表示差异:

代码语言:javascript
复制
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 测试,确保 UnifiedDiffGeneratorUtil 能在统一差异输出中正确高亮修改的行:

代码语言:javascript
复制
@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,用于生成并应用补丁以更新原始内容。它将原始字符串列表转换为修订版本:

代码语言:javascript
复制
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);
    }
}

它首先计算差异,然后将生成的补丁应用于原始内容以完成更新。

验证 PatchUtil 是否正确应用补丁,使原始列表与修订列表一致:

代码语言:javascript
复制
@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 类,提供一种可读的方式显示两个字符串列表之间的差异:

代码语言:javascript
复制
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 视图,但它会暴露每个差异(delta)的源行和目标行。这些数据可用于构建自定义的可视化表示,随后可转换为格式化的 HTML,用于基于 Web 的差异查看器。

以下测试验证了 SideBySideViewUtil.display() 方法在比较两个不同的字符串列表时不会抛出异常:

代码语言:javascript
复制
@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 Diff Utils 为 Java 应用中的文本数据比较提供了灵活、开源的解决方案。从基本的逐行差异到完整的统一差异生成和补丁功能,它是构建健壮的版本控制或变更跟踪系统的基础工具。

凭借其最少的配置和高可读性的输出,Java Diff Utils 是处理版本数据、协作编辑工具或文件监控系统的开发者的必备工具。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概述
  • 2. 理解 Java Diff Utils 及其主要优点
  • 3. 设置 Diff Utils
  • 4. 在 Java 中使用 Diff Utils
    • 4.1 比较字符串列表
    • 4.2 生成统一差异(Unified Diffs)
    • 4.3 应用补丁
    • 4.4 构建并排差异视图
  • 5. 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档