Domanda

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++;
        }
    }
}
È stato utile?

Soluzione

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?

Altri suggerimenti

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top