Database Reference
In-Depth Information
public
int
getAirTemperature
() {
return
airTemperature
;
}
}
The resulting mapper (version 2) is much simpler (see
Example 6-8
)
. It just calls the pars-
er's
parse()
method, which parses the fields of interest from a line of input, checks
whether a valid temperature was found using the
isValidTemperature()
query
method, and, if it was, retrieves the year and the temperature using the getter methods on
the parser. Notice that we check the quality status field as well as checking for missing
temperatures in
isValidTemperature()
, to filter out poor temperature readings.
NOTE
Another benefit of creating a parser class is that it makes it easy to write related mappers for similar jobs
without duplicating code. It also gives us the opportunity to write unit tests directly against the parser, for
more targeted testing.
Example 6-8. A Mapper that uses a utility class to parse records
public class
MaxTemperatureMapper
extends
Mapper
<
LongWritable
,
Text
,
Text
,
IntWritable
> {
private
NcdcRecordParser parser
=
new
NcdcRecordParser
();
@Override
public
void
map
(
LongWritable key
,
Text value
,
Context context
)
throws
IOException
,
InterruptedException
{
parser
.
parse
(
value
);
if
(
parser
.
isValidTemperature
()
) {
context
.
write
(
new
Text
(
parser
.
getYear
()
),
new
IntWritable
(
parser
.
getAirTemperature
()
));
}
}
}
With the tests for the mapper now passing, we move on to writing the reducer.
Reducer
The reducer has to find the maximum value for a given key. Here's a simple test for this
feature, which uses a
ReduceDriver
: