使用 Java 8 或流在字符串中查找第一个重复字符

Find first repeated character in a String using Java 8 or streams

我很难用 java 8 解决这个问题。我知道 提出了类似的问题。 但是该解决方案不起作用,因为它 returns "a" 作为下面给定输入的第一个重复字符。 预期输出为“e”。

请帮忙。

给定输入=“我感觉很开心”;
预期输出 = "e"

首先,使用Java8个流没有技术上的原因。 Java8个流的真正目的是让代码更简洁,更容易阅读/理解。如果您对流的理解不够透彻……或者问题出在流 ill-suited 上……那么您无法通过使用流来实现该目标。

但假设您想尝试,这里有>一个<解决方案。

import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        String input = "Feel the need";
        Set<Integer> seen = new HashSet<>();
        OptionalInt first = input.chars()
            .filter(i -> !seen.add(i))
            .findFirst();
        if (first.isPresent()) {
            System.out.println((char) first.getAsInt());
        }
    }
}

解释:

  1. String.chars() 给出 IntStream ... !!
  2. Set.add returns false 如果元素已经在集合中。
  3. 所以... filter(i -> !seen.add(i)) 正在过滤掉不在 seen 中的字符;即不重复的。
  4. first() 为我们提供了第一个重复项...或一个空的可选项。
  5. 我们需要将结果 int 转换为 char 以将其打印为字符。

注意:这相当“脏”,因为它依赖于在 seen 上执行 side-effect。如果您尝试并行化流,它将中断。此外,我们确实应该流式传输 Unicode 代码点而不是 char 值。


事实上,你的问题 的预期输出应该 是一个 space 字符,因为 SP 是字符串中第一个重复的字符!

尽管您询问了基于流的解决方案,但我认为该要求是 XY problem 的症状,因为它可以在一行中没有流的情况下完成:

String firstRepeated = str.replaceAll(".*?(.)(?=\1).*|.*", "");

哪个returns第一个重复字符,如果没有重复字符则为空字符串。