Mar*_*les 10 java mapreduce anagram java-8 java-stream
Java 8即将发布......在学习Streams的过程中,我进入了一个关于使用一种新方法对字谜进行分组的场景.我面临的问题是我找不到使用map/reduce函数对Strings对象进行分组的方法.相反,我必须创建一个与http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html中记录的类似的方式.
根据文档,我们可以简单地使用LIST.stream().collect(Collectors.groupingBy(POJO :: GET_METHOD)),这样Collectors.groupingBy()将根据使用的方法聚合地图的键.但是,这种方法似乎很难包装简单的String表示.
public class AnagramsGrouping {
static class Word {
public String original;
public Word(String word) {
original = word;
}
public String getKey() {
char[] characters = input.toCharArray();
Arrays.sort(characters);
return new String(characters);
}
public String toString() {
return original;
};
}
public static void main(String[] args) {
List<Word> words = Arrays.asList(new Word("pool"), new Word("loop"),
new Word("stream"), new Word("arc"), new Word("odor"),
new Word("car"), new Word("rood"), new Word("meats"),
new Word("fires"), new Word("fries"), new Word("night"),
new Word("thing"), new Word("mates"), new Word("teams"));
Map<String, List<Word>> anagrams = words.stream().collect(
Collectors.groupingBy(Word::getKey));
System.out.println(anagrams);
// This prints the following:
{door=[odor, rood], acr=[arc, car], ghint=[night, thing],
aemrst=[stream], efirs=[fires, fries], loop=[pool, loop],
aemst=[meats, mates, teams]}
Run Code Online (Sandbox Code Playgroud)
相反,我正在寻找一种更简单,更直接的解决方案,它使用新的map/reduce函数将结果累积到类似的接口Map中.根据/sf/answers/1462142321/,我有以下内容:
List<String> words2 = Arrays.asList("pool", "loop", "stream", "arc",
"odor", "car", "rood", "meats", "fires", "fries",
"night", "thing", "mates", "teams");
words2.stream().collect(Collectors.toMap(w -> sortChars(w), w -> w));
Run Code Online (Sandbox Code Playgroud)
但是这段代码生成了一个密钥冲突,因为它是一个1-1的Map."线程中的异常"主"java.lang.IllegalStateException:重复的密钥池",这是有意义的...有没有办法将它们分组到与groupingBy的第一个解决方案类似的输出中,但没有使用包装值的POJO ?
Stu*_*rks 19
单参数groupingBy收集器完全符合您的要求.它对您已经使用sortChars(或getKey在前面的示例中)完成的输入进行了分类.分类在相同密钥下的每个流值都被放入一个列表中,该列表是映射的值.因此我们有:
Map<String, List<String>> anagrams =
words2.stream().collect(Collectors.groupingBy(w -> sortChars(w)));
Run Code Online (Sandbox Code Playgroud)
给出输出
{door=[odor, rood], acr=[arc, car], ghint=[night, thing], aemrst=[stream],
efirs=[fires, fries], loop=[pool, loop], aemst=[meats, mates, teams]}
Run Code Online (Sandbox Code Playgroud)
您还可以使用方法参考:
Map<String, List<String>> anagrams =
words2.stream().collect(Collectors.groupingBy(GroupingAnagrams::sortChars));
Run Code Online (Sandbox Code Playgroud)
如果要对除构建列表之外的值执行某些操作,请使用多arg重载groupingBy和"下游"收集器.例如,要计算单词而不是构建列表,请执行以下操作:
Map<String, Long> anagrams =
words2.stream().collect(
Collectors.groupingBy(GroupingAnagrams::sortChars, Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)
这导致:
{door=2, acr=2, ghint=2, aemrst=1, efirs=2, loop=2, aemst=3}
Run Code Online (Sandbox Code Playgroud)
编辑:
如果不清楚,sortChars只是一个静态函数,它执行与getKey第一个例子中的函数类似的函数,但是从字符串到字符串:
public static String sortChars(String input) {
char[] characters = input.toCharArray();
Arrays.sort(characters);
return new String(characters);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15351 次 |
| 最近记录: |