1、自定义key和value组合键类NewKeyPari
public static class NewKeyPari implements WritableComparable<NewKeyPari>{
Long first;
Date second;
public Long getFirst() {
return first;
}
public void setFirst(Long first) {
this.first = first;
}
public Date getSecond() {
return second;
}
public void setSecond(Date second) {
this.second = second;
}
public NewKeyPari() {
super();
}
public NewKeyPari(Long first, Date second) {
super();
this.first = first;
this.second = second;
}
@Override
public int compareTo(NewKeyPari o) {
if (this.first != o.first) {
return this.first < o.first ? -1 : 1;
}else if (this.second.getTime() != o.second.getTime()) {
return this.second.getTime() < o.second.getTime() ? -1 : 1;
}else {
return 0;
}
}
@Override
public void readFields(DataInput dataInput) throws IOException {
this.first = dataInput.readLong();
this.second = new Date(dataInput.readUTF());
}
@Override
public void write(DataOutput dataOutput) throws IOException {
dataOutput.writeLong(first);
dataOutput.writeUTF(second.toString());
}
@Override
public String toString() {
// TODO Auto-generated method stub
return first+","+this.getSecond().toString();
}
}
自定义分区和分组,网上例子比较多,在此没有出来
自定义的map
/*
* @time 2016-05-14 20:14:17
* @author 朱海川
*/
public static class TrackAnlysMap extends Mapper<NewKeyPari, DoubleWritable, NewKeyPari, DoubleWritable>{
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
protected void map(NewKeyPari key, DoubleWritable value,
Mapper<NewKeyPari, DoubleWritable, NewKeyPari, DoubleWritable>.Context context)
throws IOException, InterruptedException {
String[] split = value.toString().split(",");
long roadid = Long.parseLong(split[0]);
Date date;
try {
date = dateFormat.parse(split[1]);
//排序都是基于key的,则就要将key和value定义成组合键.使用新的类型作为key参与排序
NewKeyPari newKeyPari = new NewKeyPari(roadid, date);
context.write(newKeyPari, new DoubleWritable(Double.parseDouble(split[2])));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
自定义的reduce
/*
* @time 2016-05-14 20:14:17
* @author 朱海川
*/
public static class TrackAnlysReduce extends Reducer<NewKeyPari, DoubleWritable, Text, DoubleWritable>{
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
@Override
protected void reduce(NewKeyPari key, Iterable<DoubleWritable> values,
Reducer<NewKeyPari, DoubleWritable, Text, DoubleWritable>.Context context)
throws IOException, InterruptedException {
int num = 0;
double sum = 0d, averagespeed =0d;
List<DoubleWritable> list = new ArrayList<>();
list.add((DoubleWritable) values);
for(int i = 0;i < list.size()-1;i++){
try {
Date initialTime = (Date)sdf.parse(list.get(0).toString());
Date keyTime = (Date)sdf.parse(list.get(i).toString());
int initialSconds = initialTime.getHours()*3600+initialTime.getMinutes()*60+initialTime.getSeconds();
int keySeconds = keyTime.getHours()*3600+keyTime.getMinutes()*60+keyTime.getSeconds();
//15 mins = 900 seconds
if ((keySeconds - initialSconds) >900) {
sum+=values.iterator().next().get();
num++;
}
//每15mins的平均速度
BigDecimal bigDecimal = new BigDecimal(sum / num);
averagespeed = bigDecimal.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
context.write(new Text(key.first.toString()+"\t"+String.valueOf(averagespeed)),
new DoubleWritable(Double.parseDouble(keyTime.toString())));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}