1. 引言

在 Java 编程中,从字符串中提取并打印不同字符(distinct characters)是文本处理和分析中的常见基础任务。本文将探讨几种处理唯一字符的高效方法,帮助你在实际开发中灵活选择最佳方案。

2. 使用 Set 集合

利用 Java 的 Set 集合是获取不同字符的简单粗暴方案。Set 会自动处理重复元素,让我们能高效收集唯一字符。以下是实现代码:

String inputString = "BBaaeelldduunngg";

@Test
public void givenString_whenUsingSet_thenFindDistinctCharacters() {
    Set<Character> distinctChars = new HashSet<>();
    for (char ch : inputString.toCharArray()) {
        distinctChars.add(ch);
    }
    assertEquals(Set.of('B', 'a', 'e', 'l', 'd', 'u', 'n', 'g'), distinctChars);
}

核心逻辑

  1. 遍历字符串的每个字符
  2. 将字符存入 HashSet(自动去重)
  3. 通过断言验证结果是否包含所有唯一字符

⚠️ 注意:HashSet 不保证字符顺序,如果需要保留原始顺序,需改用 LinkedHashSet

3. 使用 Java 流(Streams)

Java 流(Streams)提供了函数式风格的简洁方案,特别适合链式操作。以下是流式处理的实现:

@Test
public void givenString_whenUsingStreams_thenFindDistinctCharacters() {
    Set<Character> distinctChars = inputString.chars()
      .mapToObj(c -> (char) c)
      .collect(Collectors.toSet());
    assertEquals(Set.of('B', 'a', 'e', 'l', 'd', 'u', 'n', 'g'), distinctChars);
}

📌 关键步骤解析

  1. inputString.chars() → 将字符串转为 IntStream
  2. mapToObj(c -> (char) c) → 将 int 值强转回 char
  3. Collectors.toSet() → 收集为 Set(自动去重)

💡 优势:代码更简洁,且易于扩展(如需排序或过滤只需添加中间操作)。

4. 使用 LinkedHashMap

当需要保留字符首次出现的顺序时,LinkedHashMap 是理想选择。实现如下:

@Test
public void givenString_whenUsingLinkedHashMap_thenFindDistinctCharacters() {
    Map<Character, Integer> charCount = new LinkedHashMap<>();
    for (char ch : inputString.toCharArray()) {
        charCount.put(ch, 1);
    }
    assertEquals("[B, a, e, l, d, u, n, g]", charCount.keySet().toString());
}

🔑 核心机制

  • LinkedHashMap 维护插入顺序
  • 1 仅作为占位符(实际值不重要)
  • 通过 keySet() 获取按首次出现顺序排列的唯一字符

踩坑提示:若仅需唯一字符且不关心顺序,此方案会占用更多内存(相比 HashSet)。

5. 总结

在 Java 中提取字符串的不同字符,主要有三种高效方案:

方案 适用场景 特点
Set 集合 基础去重需求 代码简单,无序
Java 流 函数式处理 链式操作,可扩展性强
LinkedHashMap 需保留顺序 按首次出现顺序输出

选择建议

  • 常规去重 → HashSet
  • 需要流式操作 → Stream + Collectors.toSet()
  • 保留字符顺序 → LinkedHashMap

完整代码示例可在 GitHub 仓库 查看。


原始标题:Print Distinct Characters of a String in Java | Baeldung