Java Diff Utils 指南
1.概述
在現代軟體開發中,追蹤和視覺化不同版本文件或內容之間的變化至關重要。無論我們建構的是版本控制系統、協作編輯器或程式碼審查工具,高效地比較內容都至關重要。在 Java 中,實作此目的的一種流行方法是使用Java Diff Utils 。
本教學示範如何使用 Java Diff Utils 函式庫執行各種任務,包括逐行比較文字內容、產生統一差異、套用修補程式以恢復或修改內容以及建立並排差異檢視。
2. 了解 Java Diff 實用程式及其主要優點
Java Diff Utils 是一個輕量級且功能強大的函式庫,用於計算文字資料之間的差異。它支援字元級和行級比較,並產生統一的差異輸出。
它通常用於版本控制系統,並應用補丁將一個版本的資料轉換為另一個版本。此實用程式提供了各種類別和方法來簡化比較過程。
以下是 Java Diff Utils 的主要優點:
- 簡單:提供簡潔直覺的 API 和靜態實用方法
- 可擴展性:輕鬆與 Spring Boot 服務和控制器集成
- 跨平台:相容於任何支援 Java 的作業系統
- 開源:根據 Apache 許可自由使用和修改
這些功能使 Java Diff Utils 成為 Java 應用程式中可靠文字比較功能的理想選擇。
3. 設定 Diff Utils
在深入研究之前,我們將透過Spring Initializr使用 Maven 設定一個簡單的 Spring Boot 應用程式。
雖然 Java Diff Utils 可以在純 Java 中使用,只需手動管理 JAR 檔案和類別路徑即可,但 Spring Boot 和 Maven 可以透過pom.xml
自動處理所有依賴項,從而簡化了這個過程。這種方法不僅減少了設定時間,還確保了跨環境的更好的可移植性和一致性。 Maven 負責下載、管理和解析所有必要的構件。
首先,我們將Java Diff Utils 依賴項新增到我們的pom.xml
檔案中:
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.12</version>
</dependency>
透過此設置,Maven 可確保在編譯和執行時均可使用正確版本的 Java Diff Utils。
現在,我們可以直接使用DiffUtils
、 Patch
和UnifiedDiffUtils
等核心類別了。這些類別都是基於實用程式的,這意味著無需明確建立實例。這種設計允許直接整合到服務類別、控制器層或獨立的 Java 元件中。
4. 在 Java 中使用 Diff 實用程序
在本節中,我們將逐步建立一些基本元件,以學習如何在各種場景中使用 Java Diff Utils 函式庫。我們將探討幾個核心用例,並研究在 Java 應用程式中使用各種策略來比較文字內容的實作。我們將使用 Java Diff Utils 庫創建用於比較內容、生成 diff、應用補丁以及並排查看更改的實作。
讓我們進一步探討其核心用例和實作。
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 測試來確保UnifiedDiffGeneratorUtil
在統一差異輸出中正確地反白修改過的行:
@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);
}
}
它首先計算差異,然後應用生成的補丁來更新原始內容。
現在,我們將驗證PatchUtil
是否正確地套用了補丁,以便原始清單與修改後的清單相符:
@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 視圖,但它會公開來自差異的原始程式碼和目標行。這些可用於建立自訂的視覺化表示,然後將其轉換為適用於基於 Web 的差異檢視器的格式化 HTML。
此測試驗證在比較兩個不同的字串清單時, SideBySideViewUtil.
display()
方法是否正確執行:
@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 具有最少的設定和高度可讀的輸出,對於使用版本化資料、協作編輯工具或檔案監控系統的開發人員來說,它是必備的。
與往常一樣,這些範例的程式碼可在 GitHub 上找到。