gpt4 book ai didi

Java Streams 与 .Net (C#) LINQ

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:24:08 26 4
gpt4 key购买 nike

我需要知道 String 或 char 数组是否有重复字符,如果有,每个重复字符有多少。

使用 LINQ,我可以按以下方式进行:-

class Program {
private const string SOURCE = "appearances";

static void Main(string[] args) {
var testQ =
from ch in SOURCE
group ch by ch into testG
where testG.Count<char>() > 1
select testG;

int num;
foreach (var tg in testQ) {
num = tg.Count();
Console.Out.WriteLine("{0}, {1}", tg.ElementAt(0), num);
}

Console.ReadLine();
}
}

谁能建议我如何使用 Java 流来解决这个问题?

最佳答案

你说 Stream - 我想你的意思是 Java 8。

下面是你会怎么做:

public Map<Character, Integer> countOccurs(final char[] input) {
return countOccurs(new String(input));
}

public Map<Character, Integer> countOccurs(final String input) {
return input.chars().
collect(
HashMap::new,
(m, c) -> m.merge((char) c, 1, Integer::sum),
HashMap::putAll
);
}

我们的想法是,我们将 Stringchar 值的 IntStream 作为 int。然后我们collect()这个IntStream到一个Map;这就像函数式语言中的 foldLeft 操作。 Map.merge 方法接受一个键和一个值,以及一个合并现有值和新值(如果一个值已经在 Map 中)的 lambda - 我们传递 Integer::sum 将两个值相加。

intchar 以及 Character 的体操是遗留的 Java 问题。新的 Java 8 API 中没有原始 CharStream,所以我们必须使用 IntStream - 然后我们必须将 int 转换为 char 然后它会被自动装箱到一个 Character

示例用法:

System.out.println(countOccurs("abbccddde"));

输出:

{a=1, b=2, c=2, d=3, e=1}

如果您随后想要过滤计数,您可以简单地执行以下操作:

final Map<Character, Integer> count = countOccurs("abbccddde");
count.entrySet().stream().
filter(e -> e.getValue() > 1).
forEach(System.out::println);

这会给你:

b=2
c=2
d=3

如果您想要在逻辑上与您的 LINQ 示例类似的东西,那么这有效:

public Collection<? extends Map.Entry<Character, Integer>> countOccurs(final String input) {
return input.chars().boxed().
collect(groupingBy(identity())).entrySet().stream().
filter(e -> e.getValue().size() > 1).
map(e -> new AbstractMap.SimpleEntry<>((char)(int)e.getKey(), e.getValue().size())).
collect(toList());
}

但它真的很丑,需要一个中间集合。

附言请原谅格式化,我还不确定如何格式化长行的 Stream 操作。我相信很快就会制定风格指南。

关于Java Streams 与 .Net (C#) LINQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24448018/

26 4 0