2014-06-27 13 views
3

我需要知道一个字符串或字符数组是否有重复的字符,如果有的话每个重复的数量有多少。Java Streams v .Net(C#)LINQ

使用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流?

+0

对字符串中的字符进行排序,并统计每个字符的出现次数。 – ionutioio

回答

2

你说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 
      ); 
} 

的想法是,我们采取的char值的IntStreamString作为int。然后我们collect()这个IntStreamMap;这就像一个函数式语言中的操作foldLeftMap.merge方法采用一个键和一个值和一个lambda合并一个现有的值和新的值,如果已经在Map - 我们通过Integer::sum将两个值相加在一起。

体操与intcharCharacter是遗留的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()); 
} 

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

P.S.原谅格式化,我不确定如何格式化长行Stream操纵。我确信很快就会有风格指引。

+1

这有点晚,但标准是换行,缩进,然后.call()。这是链式方法调用总是如此。基本上,你的时间会下降到下一行。 :) –