Skl*_*ogW 6 java java-8 java-stream
我有一个单词流,我想根据相同元素(=单词)的出现对它们进行排序.
例如:{hello,world,hello}
至
Map<String, List<String>>
Run Code Online (Sandbox Code Playgroud)
你好你好你好}
世界,{世界}
到目前为止我有什么:
Map<Object, List<String>> list = streamofWords.collect(Collectors.groupingBy(???));
Run Code Online (Sandbox Code Playgroud)
问题1:流似乎丢失了他正在处理字符串的信息,因此编译器强制我将类型更改为Object,List
问题2:我不知道在胃肠道内放入什么,以同样的方式将其分组.我知道我能够处理lambda表达式中的单个元素,但我不知道如何到达每个元素的"外部"以检查是否相等.
谢谢
要获得a Map<String, List<String>>,您只需要告诉groupingBy收集器您要按标识对值进行分组,因此该函数x -> x.
Map<String, List<String>> occurrences =
streamOfWords.collect(groupingBy(str -> str));
Run Code Online (Sandbox Code Playgroud)
然而,这有点无用,因为你看到你有两次相同类型的信息.您应该查看a Map<String, Long>,其中值表示Stream中String的出现.
Map<String, Long> occurrences =
streamOfWords.collect(groupingBy(str -> str, counting()));
Run Code Online (Sandbox Code Playgroud)
基本上不是groupingBy将返回值作为List,而是使用下游收集器counting()来告诉您要计算此值出现的次数.
你的排序要求应该意味着你应该有一个Map<Long, List<String>>(如果不同的字符串看起来相同的次数怎么样?),并且当默认的toMap收集器返回一个时HashMap,它没有排序的概念,但你可以将元素存储在一个TreeMap相反的位置.
我试着总结一下我在评论中所说的内容.
你好像怎么str -> str知道"你好"或"世界"是不同的,你似乎遇到了麻烦.
首先str -> str是一个函数,也就是说,对于输入x,产生一个值f(x).例如,f(x) = x + 2是任何值x返回的函数x + 2.
这里我们使用身份功能,即f(x) = x.当您从管道中收集元素时Map,将调用此函数,以便从值中获取密钥.所以在你的例子中,你有3个身份函数产生的元素:
f("hello") = "hello"
f("world") = "world"
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.
现在collect()调用时,对于流中的每个值,您将在其上应用函数并评估结果(这将是其中的关键字Map).如果一个键已经存在,我们将获取当前映射的值,并将List我们想要放置的值(即刚刚应用该函数的值)与此先前的映射值合并.这就是为什么你最后得到一个Map<String, List<String>>.
让我们再看一个例子.现在,流包含值"hello","world"和"hey",并且我们要应用于对元素进行分组str -> str.substring(0, 2)的函数是,即获取String的前两个字符的函数.
同样,我们有:
f("hello") = "he"
f("world") = "wo"
f("hey") = "he"
Run Code Online (Sandbox Code Playgroud)
在这里你看到"hello"和"hey"在应用函数时产生相同的键,因此List在收集它们时它们将被分组,因此最终结果是:
"he" -> ["hello", "hey"]
"wo" -> ["world"]
Run Code Online (Sandbox Code Playgroud)
要与数学进行类比,你可以采用任何非双射函数,例如x 2.对于x = -2和x = 2我们有f(x) = 4.因此,如果我们通过此函数对整数进行分组,则-2和2将位于相同的"包"中.
查看源代码不会帮助您了解最初发生的情况.如果你想知道它是如何在幕后实现的话,它会很有用.但是首先尝试用更高级别的抽象来思考这个概念,然后事情会变得更加清晰.
希望能帮助到你!:)
您要搜索的KeyExtractor是标识功能:
Map<String, List<String>> list = streamofWords.collect(Collectors.groupingBy(Function.identity()));
Run Code Online (Sandbox Code Playgroud)
编辑补充说明:
Function.identity() 用一个方法返回一个'Function',它只返回它得到的参数.Collectors.groupingBy(Function<S, K> keyExtractor)提供了一个收集器,它将流的所有元素收集到一个Map<K, List<S>>.它使用keyExtractor实现来检查流的类型对象,S并K从中推导出类型的键.此键是映射的键,用于获取(或创建)添加了流元素的结果映射中的列表.| 归档时间: |
|
| 查看次数: |
3147 次 |
| 最近记录: |