要得到Map<String, List<String>>
,你只需要告訴您要GROUP BY身份值groupingBy
收藏家,所以功能x -> x
。
Map<String, List<String>> occurrences =
streamOfWords.collect(groupingBy(str -> str));
然而,這有點無用,正如你看到你有兩次相同類型的信息。您應該查看一個Map<String, Long>
,其中的值指示Stream中字符串的出現次數。
Map<String, Long> occurrences =
streamOfWords.collect(groupingBy(str -> str, counting()));
基本上而不是一個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"
到目前爲止好。
現在,當調用collect()
時,對於流中的每個值,您將對其應用該函數並評估結果(這將是Map
中的關鍵字)。如果一個密鑰已經存在,我們取當前映射的值,然後我們將我們想要放入的值(即剛剛應用該函數的值)合併到該先前映射的值中。這就是爲什麼你最後得到Map<String, List<String>>
。
再舉一個例子。現在,該流包含值「hello」,「world」和「hey」,我們想要將這些元素分組的函數是str -> str.substring(0, 2)
,即採用String的前兩個字符的函數。
同樣,我們有:
f("hello") = "he"
f("world") = "wo"
f("hey") = "he"
這裏你可以看到,這兩個「你好」和「嘿」應用功能,因此他們將在同一List
收集時,它們被組合時產生相同的密鑰,從而使最終的結果是:
"he" -> ["hello", "hey"]
"wo" -> ["world"]
要與數學打個比方,你可能會採取任何非雙射函數,如X 。對於x = -2
和x = 2
我們有f(x) = 4
。所以如果我們用這個函數對整數進行分組,-2和2將會在同一個「包」中。
查看源代碼不會幫助您瞭解最初發生的情況。如果你想知道如何在引擎蓋下實現,這很有用。但首先要考慮更高抽象層次的概念,然後事情會變得更加清晰。
希望它有幫助! :)
謝謝,一旦我確認,我會盡快給你接受的答案。 P.S .:你介意解釋這是如何工作的嗎?特別是當我使用流時,我想要在列表中獲取元素的元數據時,策略是什麼?不知何故,我似乎沒有得到它。我認爲這可能對未來的讀者有所幫助。 – SklogW
@SklogW新增說明。現在更清楚了嗎? – flo
是的,有一點點,只是一個小東西:是「s - > s」,因爲lambda表達式真的足以暗示我想要具有相同標識的元素。我不知道如何告訴功能,我想要相同的元素。 s - > s.equals(s)將是無稽之談,對吧? – SklogW