免费领取大神编写的 stream 和 lambda 技术文档请看文章尾部。
该技术文档可用来 1. 系统学习 2.忘记查阅
1.代码概览:
private static void streamProcessor(StreamsBuilder streamsBuilder) {
//创建kstream对象,同时指定从那个topic中接收消息
KStream<String, String> stream = streamsBuilder.stream("topic-input");
/**
* 处理消息的value
*/
stream.flatMapValues(new ValueMapper<String, Iterable<String>>() {
@Override
public Iterable<String> apply(String value) {
return Arrays.asList(value.split(" "));
}
})
//按照value进行分组
.groupBy((key,value)->value)
//时间窗口为10 Duration: 时间窗口
.windowedBy(TimeWindows.of(Duration.ofSeconds(10)))
//统计单词的个数
.count()
//转换为kStream
.toStream()
.map((key,value)->{
System.out.println("key:"+key+",vlaue:"+value);
return new KeyValue<>(key.key().toString(),value.toString());
})
//发送消息
.to("topic-out");
}
2.代码详解:
2.1使用streamsBuilder.stream("topic-input")
从名为"topic-input"的Kafka主题中创建一个KStream对象stream
,该流包含键值对(Key-Value)形式的数据,键为String类型,值为String类型。
2.2调用stream.flatMapValues()
方法,传入一个ValueMapper实现类的实例作为参数,对消息的值进行拆分。在这里,对每条消息的值按空格进行拆分,然后将拆分后的单词作为新的值返回。
/**
* 处理消息的value
*/
stream.flatMapValues(new ValueMapper<String, Iterable<String>>() {
@Override
public Iterable<String> apply(String value) {
return Arrays.asList(value.split(" "));
}
})
这段代码是一个实现了`ValueMapper`接口的匿名内部类,其中覆盖了`apply()`方法。
`apply()`方法中,输入参数是一个String类型的数值,作用是将这个字符串按空格进行分割,并返回一个包含分割后单词的Iterable对象。
具体来说,这个`apply()`方法的作用是将输入的字符串`value`按照空格进行分割,得到一个字符串数组,然后通过`Arrays.asList()`方法将该数组转换为一个List对象,最终返回这个List对象作为结果。换句话说,这个函数的作用是将一个字符串`value`按空格分割成单词,并以Iterable形式返回这些单词。
在上文提到的流处理方法中,这个`apply()`方法被用作`flatMapValues()`方法的参数,用于对每条消息的值进行拆分处理,将其转换为多个单词的Iterable集合。
2.2.1 flatMapValues() 方法是?
flatMapValues()方法是Stream API中的一个操作,用于对流中的每个元素的值进行拆分、转换或扁平化处理。
具体来说,对于一个KStream流对象,`flatMapValues()`方法接受一个`ValueMapper`接口的实现类作为参数。`ValueMapper`接口定义了一个`apply()`方法,用于将输入的值进行转换,并返回一个Iterable(可迭代)的结果。
在这个例子中,`flatMapValues()`方法的参数是一个匿名内部类实现了`ValueMapper`接口。在`apply()`方法中,它将输入的value按照空格进行拆分,并将拆分后的单词作为Iterable返回。
使用`flatMapValues()`方法后,原始的KStream流中的每个键值对的值会被拆分为多个新的键值对,其中键保持不变,而值被拆分后的单词所替代。这使得后续的聚合、计数等操作可以基于拆分后的单词进行处理。
总的来说,`flatMapValues()`方法用于对KStream流中的每个元素的值进行拆分、转换或扁平化处理,返回一个新的KStream流对象。
2.2.2 Iterable<String> 是?
`Iterable<String>`是Java中的一个接口,用于表示一种数据结构,其中包含一组元素,可以被迭代遍历。在这个接口中,`<String>`表示这个集合中包含的元素类型为String。
`Iterable`接口是Java集合框架中的一个基础接口,它定义了一个方法`iterator()`,返回一个用于迭代访问集合元素的迭代器(Iterator)。通过迭代器,可以依次访问集合中的每个元素,实现对集合的遍历操作。
在这段代码中,`apply()`方法返回的类型为`Iterable<String>`,表示该方法返回的是一个包含String类型元素的可迭代集合。在这里,经过处理后的单词列表被封装在一个Iterable对象中,以便后续的流处理操作可以逐个遍历处理这些单词。
总的来说,`Iterable<String>`表示一个包含String类型元素的可迭代集合,提供了对集合内元素的迭代访问能力。
2.1.3 可以被迭代遍历意思是?
"可以被迭代遍历"指的是对集合中的元素进行逐个访问的能力。在Java中,通过使用迭代器(Iterator)可以实现对集合(如List、Set、Map等)中元素的遍历。
迭代遍历是一种遍历集合元素的方法,通过迭代器,可以逐个获取集合中的元素,并按照一定的顺序进行处理或访问。迭代器提供了一些方法,如`hasNext()`用于检查是否还有下一个元素,`next()`用于获取下一个元素。
当集合实现了`Iterable`接口时,就可以通过调用`iterator()`方法获取到一个迭代器对象。通过这个迭代器对象,可以使用循环结构(如`while`或`for`循环)来遍历集合中的每个元素,直到遍历完所有元素为止。
例如,在这个代码片段中,返回的`Iterable<String>`代表一个包含字符串类型元素的可迭代集合。我们可以使用迭代器来遍历这个集合中的每个字符串,依次进行处理。
总之,"可以被迭代遍历"意味着我们可以使用迭代器来逐个访问集合中的元素,以便对它们进行处理或进行其他操作。
2.3 调用groupBy()
方法按照值进行分组,以便后续的统计操作。
注意:
java 8新特性 stream流中的知识,如想系统学习或保留查阅,请联系作者,看文章末尾,免费领取文档。另外附赠lambda相关文档。
.groupBy((key,value)->value)
(key, value) -> value
表达式的完整写法是一个Lambda表达式:表示从键值对中获取值的操作。
完整写法:
Function<Map.Entry<KeyType, ValueType>, ValueType> function = entry -> entry.getValue();
2.4 调用windowedBy(TimeWindows.of(Duration.ofSeconds(10))
方法定义时间窗口为10秒,用于对消息进行窗口化处理。
2.4.1窗口化处理的意思是?
对消息进行窗口化处理指的是将连续的消息流按照一定的规则进行分组或者切割,形成一个个时间窗口,并对每个窗口内的消息进行处理或聚合操作。这种处理方式通常用于实时数据流处理、时间序列分析等场景。
窗口化处理可以基于时间、消息数量或其他特定的条件进行窗口的定义。例如,基于时间的窗口可以是固定长度的时间段,比如每5分钟形成一个窗口;基于消息数量的窗口可以是每收到10条消息就形成一个窗口。
一旦窗口形成,通常会对窗口内的消息进行聚合、过滤、统计或其他处理操作,以便对整个窗口的数据进行分析或进一步处理。窗口化处理在实时数据分析、流式计算等领域具有广泛的应用,能够有效地处理大规模的实时数据流并进行实时分析和决策。
2.5 调用count()
方法对单词进行计数统计。
2.6 调用toStream()
方法将统计结果转换为KStream流,以便后续处理。
2.7 调用 map()
方法对结果进行处理,输出每个单词的统计数量,并将结果转换为KeyValue对象。
java 8新特性 stream流中的知识,如想系统学习或保留查阅,请联系作者,看文章末尾,免费领取文档。另外附赠lambda相关文档。
2.8 最后调用to("topic-out")
将处理后的结果发送到名为"itcast-topic-out"的Kafka主题中。
3.联系作者:获取系统详细的stream查阅资料并附赠lambda系统查阅资料。
1. 加好友前请先收藏点赞,感谢您
2. 加好友时请说明来意,否则可能不被通过
封面图片: