“通用”原始数组的解决方案?
我有用于处理原始数组输入的类:char[]的CharArrayExtractor,byte[]的ByteArrayExtractor,int[]的IntegerArrayExtractor,...
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.
}
}
这里的问题是提取数据的算法是相同的,只有类型输入不同。每次算法发生变化时,我都必须更改所有提取器类。
有没有办法让提取器类更加“泛型”?
此致。
编辑:到目前为止,似乎每个建议都是使用自动装箱来归档通用的。但数组的元素数量通常很大,所以我避免使用自动装箱。
我添加了如何提取数据的更具体的实现。希望它能澄清一些事情。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
新想法
或者一种不同的方法是包装原始数组并用您用于算法的方法覆盖它们。
这主要取决于您是否有很多需要调用的方法。但至少您不能在如何访问原始数组的方式上更多地编辑算法。此外,您还可以在包装器内使用不同的对象。
旧想法
要么使用泛型,要么我也想到的是使用三种方法将原始类型转换为值类型。
ArrayUtils 是来自 Apache 的 commons lang 的帮助程序类。
New Idea
Or a different approach is wrapping the primitive arrays and covering them with the methods you use for your algorithm.
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.
ArrayUtils is a helper class from commons lang from Apache.
我不确定您的过滤器将如何工作,因为它不知道有关数组包含的类型的任何信息。
使用反射你可以做你想做的事,但你会失去编译时类型安全性。
java.lang.reflect.Array 类提供了在不知道数组类型的情况下操作数组的函数。
Array.get() 函数将返回所请求的数组索引处的值,如果它是基元,则将其包装在其相应的对象类型中。缺点是您必须更改方法签名以接受 Object 而不是特定的数组类型,这意味着编译器无法再为您检查输入参数。
您的代码将变成:
就我个人而言,我更喜欢使用类型安全而不是使用反射,即使它有点冗长。
I'm not sure how your filter will work as it will not know anything about the type the array contains.
Using reflection you can possibly do what you want but you will loose compile time type safety.
The java.lang.reflect.Array class provides functions for manipulating an array without knowing its type.
The Array.get() function will return the value at the requested index of the array and if it is a primitive wrap it in its corresponding Object type. The downside is you have to change your method signature to accept Object instead of specific array types which means the compiler can no longer check the input parameters for you.
Your code would become:
Personally I would prefer having type safety over using reflection even if it is a little more verbose.
不要传递每种类型,而是传递该类型的类,如下所示:
Instead of passing each type, pass the class of the type as the below:
http://download.oracle.com/javase/tutorial/extra/generics /methods.html
http://download.oracle.com/javase/tutorial/extra/generics/methods.html
你可以做这样的事情。
您将拥有一个通用的 Extractor 类,并且您的实现将是相同的。
You could do something like this.
You would have a generic Extractor class and your implementation would be the same.
由于原始类型源,您无法使用 Java 泛型,您最好的选择是尝试一些 java 反射 api 来分析传入的源并自行调用提取器。
You cant use Javas generics because of primitive type source, your best bet is to try some java reflection api to analyze the incoming source and invoke the extractors on your own.
我认为可以创建这样的方法:
并使用 Arrays.asList(yourPrimaryArrayType) 使其兼容。
经过我的测试和 Sean Patrick Floyd 的评论后,您将能够通过创建一些辅助方法来实现此目的,用于将原始数组转换为列表:
I think is is possible to do create a method like this:
And use
Arrays.asList(yourPrimaryArrayType)
, to make it compatible.After my tests and the comment of Sean Patrick Floyd, you will be able to do this by create once some helper methods, for converting primitive arrays to lists:
不,这是不可能的。
例如,查看
此外,我们可以更多地讨论泛型的工作原理,但我想这将是另一个问题。
No, it is never possible.
For example take a look at documentation of ArrayUtils.copyOf(byte[] original, int newLength). And there exists other methods for remaining primitives. This is kind of same behavior (literally) you wanted. If it was possible similar code should exists somewhere else.
Additionally we can discuss more about how generic works, but it would be another issue, i guess.
取决于您想要实现的目标。但也许您可以使用原始包装器?然后你可以编写通用的
Extractor
(这里Number
是由所有原始包装器扩展的抽象类)。Depends on what you're trying to achieve. But maybe you can work with primitive wrappers instead? Then you could write generic
Extractor<? extends Number>
(hereNumber
is the abstract class extended by all primitive wrappers).是的,您应该能够使用泛型:
在这里,您必须假设
T
是一个基元数组,因为您不能在泛型定义中使用基元。或者,您可以使用包装器对象并这样做:
在这种情况下,您的通用
T
可以是Byte
、Integer
等。Yes, you should be able to use generics:
Here, you would have to assume that
T
is a primitive array, as you cannot use primitives in generic definitions.Or else, you could use the wrapper Objects and do it this way:
In this case, your generic
T
can beByte
,Integer
, etc.