@Override
 public void evicted(WindowItem item) {
   if (item.getEvent().get(operatedField) != null) {
     try {
       evict((F) item.getEvent().get(operatedField).getValue());
     } catch (ClassCastException e) {
       throw new FlowmixException(
           "Problem converting value " + item.getEvent().get(operatedField).getValue(), e);
     }
   }
 }
 /**
  * 假设根据year,age统计count:select year,age,count(*) from table group by year,age
  * 则groupByFields=[year,age], operateField=?
  *
  * @param item
  */
 @Override
 public void added(WindowItem item) {
   // 第一个窗口项(事件)进来时满足条件.后面的窗口项因为groupedValues!=null,不满足条件.
   if (groupedValues == null && groupByFields != null) {
     groupedValues = new HashMap<String, Collection<Tuple>>();
     for (String group : groupByFields) {
       groupedValues.put(group, item.getEvent().getAll(group));
     }
   }
   if (item.getEvent().get(operatedField) != null) {
     try {
       // 参数是事件记录中操作字段的值. 而不是事件记录本身.比如要聚合sum(key3),则我们要把key3的值取出来,作为sum的参数
       add(((F) item.getEvent().get(operatedField).getValue()));
     } catch (ClassCastException e) {
       throw new FlowmixException(
           "Problem converting value " + item.getEvent().get(operatedField).getValue(), e);
     }
   }
   // TODO: 关联字段
   if (assocField != null) {
     try {
       // 如果关联的两个字段类型不同呢, 所以最好自定义的Aggregator的F为Object类型.
       add(
           ((F) item.getEvent().get(assocField[0]).getValue()),
           ((F) item.getEvent().get(assocField[1]).getValue()));
     } catch (ClassCastException e) {
       throw new FlowmixException(
           "Problem converting value " + item.getEvent().get(assocField[0]).getValue(), e);
     }
   }
 }