patternjavaMinor
Two Key HashMap
Viewed 0 times
twohashmapkey
Problem
Background
Would like to create a two-key map that is fairly generic. In the existing system, there are a number of ways to name a parameter for a report. Rather than re-writing each report (too much effort), we'd like to simply map the old parameter names to new names.
For example, old names might include
By using a consistent naming scheme, we could, for example, detect the data type (e.g., by following a convention such as ending parameters in the data type, as in
Code
The existing code resembles:
Question
How would you improve the code so that it is easier for new and intermediate Java developers to maintain?
For example, would this be easier:
```
TwoKeyMap tkm = new TwoKeyMap();
tkm.put( ReportNames.REPORT1, Parameter.P_START_DATE, "P_DATE_START" );
tkm.put( ReportNames.REPORT1, Parameter.P_END_DATE, "P_DATE_END" );
tkm.pu
Would like to create a two-key map that is fairly generic. In the existing system, there are a number of ways to name a parameter for a report. Rather than re-writing each report (too much effort), we'd like to simply map the old parameter names to new names.
For example, old names might include
STARTDATE, FROM_DT, P_DATE_START, and countless more variations thereof each being mapped to a single, equivalent P_START_DATE.By using a consistent naming scheme, we could, for example, detect the data type (e.g., by following a convention such as ending parameters in the data type, as in
_DATE) and then automatically generate a corresponding web page complete with validation for the report's form submission. This is otherwise an arduous task with an inconsistent naming scheme across hundreds of legacy reports.Code
The existing code resembles:
public class TwoKeyMap {
private enum Parameter {
P_START_DATE,
P_END_DATE;
}
private static final Map>
REPORT_PARAMETER_MAP = new HashMap>() {
{
put("ReportName", new HashMap() {
{
put(Parameter.P_START_DATE, "P_DATE_START");
put(Parameter.P_END_DATE, "P_DATE_END");
}
});
}
};
/**
* Retrieves the old parameter name based on the report using the new parameter name.
*
* @param report - The report name having a parameter mapped to a new name.
* @param key - The new name of the parameter.
* @return The report's old parameter name.
*/
public static String lookupParameter(String report, Parameter key) {
return getReportParameterMap().get(report).get(key);
}Question
How would you improve the code so that it is easier for new and intermediate Java developers to maintain?
For example, would this be easier:
```
TwoKeyMap tkm = new TwoKeyMap();
tkm.put( ReportNames.REPORT1, Parameter.P_START_DATE, "P_DATE_START" );
tkm.put( ReportNames.REPORT1, Parameter.P_END_DATE, "P_DATE_END" );
tkm.pu
Solution
I'd go with something which is similar to the mentioned
(Make sure that is has proper
I think it's easier to understand than the nested maps (for example,
Furthermore, I'd consider creating and using different types (!= string) for the report name and the parameter names. String identifiers are hard to follow and it's easy to accidentally mix them up. Different types (for example, enums, like
A sidenote from Code Complete 2nd Edition, Chapter 5: Design in Construction, Value of Information Hiding, page 96:
[...]
Most programmers would decide, “No, it isn’t worth creating a whole class just
for an ID. I’ll just use ints.”
[...]
Rather, the difference is one of heuristics—thinking about information
hiding inspires and promotes design decisions that thinking about objects
does not.
MultiKey: create a ReportParameter class and use it as the key of the map:public class ReportParameter {
private final String reportName;
private final Parameter parameter;
public ReportParameter(final String reportName, final Parameter parameter) {
this.reportName = reportName;
this.parameter = parameter;
}
// equals and hashCode here
}(Make sure that is has proper
hashCode and equals methods.)I think it's easier to understand than the nested maps (for example,
Map>).Furthermore, I'd consider creating and using different types (!= string) for the report name and the parameter names. String identifiers are hard to follow and it's easy to accidentally mix them up. Different types (for example, enums, like
Parameter) and type safety help here.A sidenote from Code Complete 2nd Edition, Chapter 5: Design in Construction, Value of Information Hiding, page 96:
[...]
Most programmers would decide, “No, it isn’t worth creating a whole class just
for an ID. I’ll just use ints.”
[...]
Rather, the difference is one of heuristics—thinking about information
hiding inspires and promotes design decisions that thinking about objects
does not.
Code Snippets
public class ReportParameter {
private final String reportName;
private final Parameter parameter;
public ReportParameter(final String reportName, final Parameter parameter) {
this.reportName = reportName;
this.parameter = parameter;
}
// equals and hashCode here
}Context
StackExchange Code Review Q#22769, answer score: 4
Revisions (0)
No revisions yet.