I have classes that for processing primitive array input: CharArrayExtractor for char[], ByteArrayExtractor for byte[], IntegerArrayExtractor for int[], ...
public void CharArrayExtractor {
public List<Record> extract(char[] source) {
List<Record> records = new ArrayList<Record>();
int recordStartFlagPos = -1;
int recordEndFlagPos = -1;
for (int i = 0; i < source.length; i++) {
if (source[i] == RECORD_START_FLAG) {
recordStartFlagPos = i;
} else if (source[i] == RECORD_END_FLAG) {
recordEndFlagPos = i;
}
if (recordStartFlagPos != -1 && recordEndFlagPos != -1) {
Record newRecord = makeRecord(source, recordStartFlagPos,
recordEndFlagPos);
records.add(newRecord);
recordStartFlagPos = -1;
recordEngFlagPos = -1;
}
}
}
}
public void ByteArrayExtractor {
public List<Record> extract(byte[] source) {
// filter and extract data from the array.
}
}
public void IntegerArrayExtractor {
public List<Record> extract(int[] source) {
// filter and extract data from the array.
}
}
The problem here is that the algorithm for extracting the data is the same, only the types of input are different. Everytime the algorithm changes, I have to change all of the extractor classes.
Is there a way to make extractor classes more "generics"?
Best regards.
EDIT: It seems that every suggestion so far is to use autoboxing to archive generic. But the number of elements of the array is often large, so I avoid using autoboxing.
I added more specific implementation of how the data is being extracted. Hope it will clarify something.
New Idea
Or a different approach is wrapping the primitive arrays and covering them with the methods you use for your algorithm.
public PrimitiveArrayWrapper {
private byte[] byteArray = null;
private int[] intArray = null;
...
public PrimitiveArrayWrapper(byte[] byteArray) {
this.byteArray = byteArray;
}
// other constructors
public String extractFoo1(String pattern) {
if(byteArray != null) {
// do action on byteArray
} else if(....)
...
}
}
public class AlgorithmExtractor {
public List<Record> do(PrimitiveArrayWrapper wrapper) {
String s= wrapper.extractFoo1("abcd");
...
}
}
This mainly depends if you have a lot of methods to call which you would have to cover. but at least you must not edit the algorithm more over the way how to access the primitive array. Furthermor you would also be able to use a different object inside the wrapper.
Old Idea
Either use generics or what i also think about is to have three methods which convert the primitive types into value types.
public void Extractor {
public List<Record> extract(byte[] data) {
InternalExtractor<Byte> ie = new InternalExtractor<Byte>();
return ie.internalExtract(ArrayUtils.toObject(data));
}
public List<Record> extract(int[] data) {
...
}
}
public void InternalExtractor<T> {
private List<Record> internalExtract(T[] data) {
// do the extraction
}
}
ArrayUtils is a helper class from commons lang from Apache.