Reputation: 688
I ran into a little snag with the concrete implementation of strategy components using generic types.
Wondering if anyone can point me in the right direction with an example?
Here is what I am working towards, but I get caught up when I declare the decode method as it expcects a List when I create the ArrayList... Not a surprise.
public class CsvFormat<T,T1> implements FormatStrategy<T,T1> {
public CsvFormat(boolean header) {
setHeader(header);
@Override
public final T decode(T1 csvData) {
csvData = new ArrayList(); //ERROR****
List<Map<String, String>> decodedData = new ArrayList<Map<String, String>>(); //turn collection into an array of maps
if (this.hasHeader()) {
decodeDataWithHeader(csvData, decodedData);
} else {
decodeDataNoHeader(csvData, decodedData);
}
return decodedData;
}
private void decodeDataNoHeader(List<String> csvData, List<Map<String, String>> records) {
int recordCount = FIRST_IDX;
List<String> fields = null; //= Arrays.asList(csvData.get(recordCount).split(DELIM)); //turn line into a list, first record
for (String data : csvData) { //for each unformatted string
int delimIndex = FIRST_IDX; //reset delim
fields = Arrays.asList(data.split(DELIM));//after header, start mapping
records.add(new LinkedHashMap<String, String>()); //make a new map
recordCount++;
for (String field : fields) {
final String KEY_ID = "Column-" + (delimIndex + RECORD_BUFFER);
records.get(records.size() - RECORD_BUFFER).put(KEY_ID, field);
delimIndex++;
}
}
}
Here is what I had to start with The only way I can think of so far to achieve the above without error is to overload the the decode methods based on what object they are passed..
public class CsvFormat implements FormatStrategy<
List<Map<String, String>>, List<String>> {
public CsvFormat(boolean header) {
setHeader(header);
}
@Override
public final List<Map<String, String>> decode(List<String> csvData) {
List<Map<String, String>> decodedData = new ArrayList<Map<String, String>>(); //turn collection into an array of maps
if (this.hasHeader()) {
decodeDataWithHeader(csvData, decodedData);
} else {
decodeDataNoHeader(csvData, decodedData);
}
return decodedData;
}
private void decodeDataNoHeader(List<String> csvData, List<Map<String, String>> records) {
int recordCount = FIRST_IDX;
List<String> fields = null; //= Arrays.asList(csvData.get(recordCount).split(DELIM)); //turn line into a list, first record
for (String data : csvData) { //for each unformatted string
int delimIndex = FIRST_IDX; //reset delim
fields = Arrays.asList(data.split(DELIM));//after header, start mapping
records.add(new LinkedHashMap<String, String>()); //make a new map
recordCount++;
for (String field : fields) {
final String KEY_ID = "Column-" + (delimIndex + RECORD_BUFFER);
records.get(records.size() - RECORD_BUFFER).put(KEY_ID, field);
delimIndex++;
}
}
}
Upvotes: 0
Views: 73
Reputation: 12305
The code you have written for decoding the data will always return a List<Map<String, String>>
and can only work with a List<String>
as input, so there is no reason for the CsvFormat
class to have type parameters. So what you started with seems correct, why aren't you satisfied with it?
Upvotes: 1
Reputation: 5239
Actually the example you "started with" seems exactly right. You have written a decode
method that requires a List<String>
as input, so it stands to reason that you would be implementing the FormatStrategy
interface with that specific type as T1
and the same goes for the output type T
.
Why would you do icky runtime inspection of the input and loads of unsafe casting when you can actually follow the pattern and create a new class for each specific concrete type you care about?
Upvotes: 1