终于实现Strips算法了,蛋疼啊。
分享部分代码,只是为了实现基本功能,
异常捕获处理什么的等细节都没考虑。
为了和算法描述一致,在Map类cleanup函数中
又化归了一下。如果不要求严格的话,直接可以
省略这一步,在Reduce中再处理。
粘帖如下:
Map类:
public static class MyMap extends Mapper<LongWritable, Text, Text, MaruCounter> {
private Long counterM=new Long(1); //output.collect value
private String fan1 = new String();
private String fan2 = new String();
private HashMap<Text, MaruCounter> inContextM;
public void map(LongWritable key, Text value, Context context)
throws IOException , InterruptedException {
String line = new String(value.getBytes(),0,value.getLength(),"sjis"); //sjis:キャラクタのパラメータ( 日本語を指定する)
StringTokenizer tokenizer = new StringTokenizer(line);
String strvalue = new String();
int column = 0; //列の番号
//start while1
while (tokenizer.hasMoreTokens()){
column += 1;
strvalue = tokenizer.nextToken();
strvalue = strvalue.trim();//move space if there is.
switch(column){
case 90:
//inFan1
fan1 = strvalue;
break;
case 91:
//inFan2
fan2 = strvalue;
Text tmpkeyM = new Text();
if (isOn(fan1)){
if (isOn(fan2)){
tmpkeyM.set("3");
}else {
tmpkeyM.set("2");
}
}else {
if (isOn(fan2)){
tmpkeyM.set("1");
}else {
tmpkeyM.set("0");
}
}
if (inContextM.containsKey(tmpkeyM)) {
MaruCounter tmpvalueM = new MaruCounter();
tmpvalueM = inContextM.get(tmpkeyM);
tmpvalueM.plusCounter();
inContextM.put(tmpkeyM, tmpvalueM);
} else {
MaruCounter tmpvalueM = new MaruCounter(fan2, counterM);
inContextM.put(tmpkeyM, tmpvalueM);
}
break;
default:
//
break;
}//end switch(column)
}//end while1
}//end map
//do once at MapTask startup
@Override
protected void setup(Context context) {
inContextM = new HashMap<Text, MaruCounter>();
}
//do once at MapTask end up
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
Text keyM = new Text();
for (Entry<Text,MaruCounter> m : inContextM.entrySet()) {
if (Integer.parseInt((m.getKey()).toString()) >=2 ){
keyM.set("●");
}else{
keyM.set("○");
}
context.write(keyM, m.getValue());
}
}
}//end Mapclass
Reduce类:
public static class MyReduce extends Reducer<Text, MaruCounter, Text, DoubleWritable> {
private Text keyR = new Text(); //output.collect key
private DoubleWritable valueR = new DoubleWritable(); //output.collect value
private HashMap<Text, Integer> inContextR;
private Text keyOn = new Text("On");
private Text keyOff = new Text("Off");
public void reduce(Text key, Iterable<MaruCounter> values, Context context)
throws IOException , InterruptedException {
int sumOn = 0;
int sumOff = 0;
//start for
for(MaruCounter value : values) {
if (isOn(key.toString())){
if (isOn(value.getMaru())){
sumOn += value.getCounter();
if (inContextR.containsKey(keyOn)) {
inContextR.put(keyOn, inContextR.get(keyOn) + sumOn);
} else {
inContextR.put(keyOn, sumOn);
}
}else{
sumOff += value.getCounter();
if (inContextR.containsKey(keyOff)) {
inContextR.put(keyOff, inContextR.get(keyOff) + sumOff);
} else {
inContextR.put(keyOff, sumOff);
}
}
}
}//end for
}//end reduce
@Override
protected void setup(Context context) {
inContextR = new HashMap<Text, Integer>();
}
@Override
protected void cleanup(Context context) throws IOException, InterruptedException {
Double rate = new Double(0);
int on = inContextR.get(keyOn);
int off = inContextR.get(keyOff);
rate = (on*1.00)/(on + off);
valueR.set(Math.round(rate*1000)/1000.0);
keyR.set("FanOnRate:");
context.write(keyR, valueR);
}
}//end Reduce class
MaruCounter类:
public class MaruCounter implements WritableComparable<MaruCounter> {
private Text maru;
private Long counter;
public MaruCounter() {
set(new Text(), new Long(0));
}
public MaruCounter(String maru, Long counter) {
set(new Text(maru), counter);
}
public MaruCounter(String maru, String counter) {
set(new Text(maru), Long.parseLong(counter));
}
public MaruCounter(Text maru, Text counter) {
set(maru, Long.parseLong(counter.toString()));
}
public void set(Text maru, Long counter) {
this.maru = maru;
this.counter = counter;
}
public void set(String maru, String counter) {
this.maru = new Text(maru);
this.counter = new Long(counter);
}
public Text getMaru() {
return maru;
}
public Long getCounter() {
return counter;
}
public void plusCounter() {
counter++;
}
@Override
public void write(DataOutput out) throws IOException {
maru.write(out);
WritableUtils.writeVLong(out, counter);
//counter.write(out);
}
@Override
public void readFields(DataInput in) throws IOException {
maru.readFields(in);
counter = WritableUtils.readVLong(in);
//counter.readFields(in);
}
@Override
public int hashCode() {
return maru.hashCode() * 157 + counter.hashCode();
}
@Override
public boolean equals(Object o) {
if (o instanceof MaruCounter) {
MaruCounter tp = (MaruCounter) o;
return maru.equals(tp.maru) && (counter == tp.counter);
}
return false;
}
@Override
public String toString() {
return maru + "\t" + String.valueOf(counter);
}
@Override
public int compareTo(MaruCounter tp) {
int cmp = maru.compareTo(tp.maru);
return (cmp != 0 ? cmp : (counter.compareTo(tp.counter)));
}
// ^^ MaruCounter