主要区别:
keyby可以传入两个参数 ①比较的值的位置 ②布尔值;min只能传入一个参数
而二者真正的区别就是第二个参数,keyby的第二个参数为false且两次输入的数据值相等的时候,可以更新为最新字段,如a,a,1 a,b,1得到的结果是a,b,1,第二个参数默认值为true,是true就会返回原先的值。下图是通过debug的结果(值1是原先的值,值2是输入的新值):
注:o1是已经存在的值,o2是输入值,源码中是将o1与o2进行比较
public class MinByDemo {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStreamSource<String> source = env.socketTextStream("localhost", 8888);
// SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = source.map(t -> Tuple2.of(t, 1)).returns(Types.TUPLE(Types.STRING, Types.INT));
KeyedStream<Tuple3<String, String, String>, String> keyed = source.map(new MapFunction<String, Tuple3<String, String, String>>() {
@Override
public Tuple3<String, String, String> map(String value) throws Exception {
String[] split = value.split(",");
return Tuple3.of(split[0], split[1], split[2]);
}
}).keyBy(new KeySelector<Tuple3<String, String, String>, String>() {
@Override
public String getKey(Tuple3<String, String, String> value) throws Exception {
return value.f0;
}
});
// KeyedStream<Tuple2<String, Integer>, Tuple> kyed = wordAndOne.keyBy(0);
//如果输入的是两个字段。那么min和minby返回值一样,没什么区别
/**
* 测试用三个字段
* a,A,10
* a,B,100
* a,A,2
* b,A,1000
* b,A,50
*/
/**
* compare源码:将此对象与指定对象进行比较。返回一个
* 负整数,零或正整数,因为此对象较小
* 大于,等于或大于指定的对象。
*
* o1是已经存在的值,o2是输入值,大于就返回1等于返回0小于返-1
* if (byAggregate) {
* // if they are the same we choose based on whether we want to first or last
* // element with the min/max.
* if (c == 0) {
* return first ? value1 : value2;
* }
*
* return c == 1 ? value1 : value2;
* * } else {
* if (c == 0) {
* value1 = fieldAccessor.set(value1, o2);
* }
* return value1;
* }
*
*/
/**
* keyby可以传入两个参数 ①比较的值的位置 ②布尔值
*/
//1.为false时,如果两次比较的值相等,那么返回的是最新字段(且会对第二个字段在进行比较)
//2.第二个参数不输入,与第二种结果返回的结果一样。所以这里默认应该是false
//这个false的作用就是 如果两次值相等,那么返回的是最新值
// SingleOutputStreamOperator<Tuple3<String, String, String>> min = keyed.minBy(2, true);
/**
* o1是已经存在的值,o2是输入值
* if (c == 0) {
* return first ? value1 : value2;
* }
*/
//min只能传一个参数,不会有false和true的输入,所以不会对于中间的参数,不会去更新,min和minBy最终都是调用的reduce方法
//因为输入false后,输入三个元素,中间的元素保持不变,那么第二个参数默认的就是true
SingleOutputStreamOperator<Tuple3<String, String, String>> min = keyed.min("f2");
//min 方法返回的值是按?排序和比较值是变化的,其他的值是固定的
min.print();
/**
* 测试结果
* 6> (a,d,89)
* 6> (a,d,89)
* 6> (a,d,88)
* 2> (b,a,88)
* 2> (b,a,87)
* 2> (b,a,87)
* 2> (b,a,86)
*/
env.execute();
}
}