Java Streams 与 .Net (C#) LINQ

标签 java c#-4.0

我需要知道 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/

相关文章:

wpf - wpf mvvm使用命令在 View 模型之间传递参数

java - 我如何在 Java 中的多个线程之间共享资源?

java - 绘制多边形: unable to find error

c# - Assembly.GetExecutingAssembly() 和 typeof(program).Assembly 之间的区别

c# - 如何查看是否配置了代理服务器?

sql - 如何在列的 sql select 语句中插入新的 guid

c# - 将 Json 字符串转换为对象列表

java - 如何使 LibGDX 应用程序以与浏览器框架相同的分辨率启动

java - Guice多数据库自动切换

java - 如何在 Java 中设置自定义光标?