I have a bunch of manager classes which manage different objects like state, country and so on. getObjects()
method returns a list of such objects, values of these lists are appended in different methods like the following ones:
//states - StateManager.java
public String getStateMsg() {
StringBuilder msg = new StringBuilder();
if (states != null) {
for (State state : states.getObjects()) {
msg.append(state.getStateCd())).append(" ");
}
}
return msg.toString().trim();
}
//codes - CodeManager.java
public String getCodeMsg() {
StringBuilder msg = new StringBuilder();
if (codes != null) {
for (Code code : codes.getObjects()) {
msg.append(code.getCd()).append(" ");
}
}
return msg.toString().trim();
}
//countries - CountryManager.java
public String getCountriesMsg() {
StringBuilder msg = new StringBuilder();
if (countries != null) {
for (Country country : countries.getObjects()) {
msg.append(countries.get(country.getCountryCd())).append(" ");
}
}
return msg.toString().trim();
}
There's obvious code duplication and I want to make general solution where a method takes a collection (retrieved by getObjects()
) and returns a list of strings.
I found that guava can make some sort of collection transformations from one type to another. But classes in the example (State, Code, Country) do not share any general interface. From the other hand, a method which will take collection of objects and method name to retrieve value of a specific object field, means usage of reflection that isn't a good idea.
As a result I have a question, is it possible to avoid described code duplication and make a utility method which will take collection of objects and return collection of strings?
If you don't have Java 8, use generics and Guava Function:
public static <T, U> String getGenericMsg(List<T> genericList, Function<T, U> function) {
StringBuilder msg = new StringBuilder();
if (genericList != null) {
for (T genericObject : genericList) {
msg.append(function.apply(genericObject)).append(" ");
}
}
return msg.toString().trim();
}
private static Function<State, String> STATE_TO_STRING = new Function<State, String>() {
public String apply(State input) {
return input.getStateCd();
}
};
private static Function<Code, String> CODE_TO_STRING = new Function<Code, String>() {
public String apply(Code input) {
return input.getCd();
}
};
private static Function<Country, String> COUNTRY_TO_STRING = new Function<Country, String>() {
public String apply(Country input) {
return input.getCountryCd();
}
};
Finally your client code:
public void yourClientMethod() {
getGenericMsg(states, STATE_TO_STRING);
getGenericMsg(codes, CODE_TO_STRING);
getGenericMsg(countries, COUNTRY_TO_STRING);
}