我正在尝试理解Java中流的数据流。我的任务是将每个字符串中出现的字母放入列表中。
List<String> words = Arrays.asList("Welcome", "to", "the", "java", "world");
进入
Map<String, Long>
使用一行流的方式。
我知道,我们可以首先从列表中流式传输每个单词,然后需要将其分成字符,将每个字符作为键并计算其出现次数作为值,最后返回整个映射。
这很复杂难懂。有人能解释一下怎么做吗?
我正在尝试理解Java中流的数据流。我的任务是将每个字符串中出现的字母放入列表中。
List<String> words = Arrays.asList("Welcome", "to", "the", "java", "world");
进入
Map<String, Long>
使用一行流的方式。
我知道,我们可以首先从列表中流式传输每个单词,然后需要将其分成字符,将每个字符作为键并计算其出现次数作为值,最后返回整个映射。
这很复杂难懂。有人能解释一下怎么做吗?
Map<Character, Long> charFrequency = words.stream() //Stream<String>
.flatMap(a -> a.chars().mapToObj(c -> (char) c)) // Stream<Character>
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
flatMapToInt
比使用flatMap(a -> a.chars().mapToObj(c -> (char) c))
更易读。words.stream()
.flatMapToInt(String::chars) //IntStream
.mapToObj(c -> (char) c) //Stream<Character>
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
flatMap
是一个函数,你可以使用它将字符串转换为单个字符。而普通的 map
函数只是将每个流元素转换为不同的元素,flatMap
将每个元素转换为一个元素的流,然后将这些流连接在一起。String
转换为字符流的函数是 String.chars
。Collectors.groupingBy
,你可以生成一个收集器,该收集器将创建一个Map
,给定两个函数,一个用于为每个流值产生键,另一个用于产生值。还有一个变体,可以让你将另一个收集器作为第二个参数传递进去,而不是一个函数;试试 Collectors.counting
。在 Kotlin 中:
val str = "Occurrences"
val results: Map<String, Long> =
stream(str.split("").toTypedArray()).map{n-> n.lowercase()}
.collect(
Collectors.groupingBy({ it },
{ LinkedHashMap() },
Collectors.counting()
)
)
Log.w("occurrencesResult",results.toString())
List<String> words = Arrays.asList( "", "Welcome", "to", "the", "java", "world" );
的结果是:{a=2, c=1, d=1, e=3, h=1, j=1, ?=1, l=2, m=1, o=3, r=1, t=2, v=1, w=1, W=1, ?=1},可以在 IdeOne.com 上运行 查看。 - Basil Bourquea.codePoints().mapToObj(i -> new StringBuilder().appendCodePoint(i).toString())
或类似的代码。 - MC Emperor