我有一个过滤器类,其中用户必须声明类型(例如Filter<Double>
,Filter<Float>
等)。该类随后实现了移动平均滤波器,因此必须添加该类中的对象。我的问题是怎么做?我很抱歉,如果答案很简单,但我想太多了,以至于我陷入了困惑:p。
public abstract class FilterData<T>
{
private final List<T> mFilter;
private T mFilteredValue; // current filtered value
protected Integer mSize = 10;
private T mUnfilteredValue; // current unfiltered value
public FilterData()
{
mFilter = new ArrayList<T>();
}
public FilterData(int size)
{
mSize = size;
mFilter = new ArrayList<T>(mSize);
}
public abstract T add(final T pFirstValue, final T pSecondValue);
@SuppressWarnings("unchecked")
public T filter(T currentVal)
{
T filteredVal;
mUnfilteredValue = currentVal;
push(currentVal);
T totalVal = (T) (new Integer(0));
int numNonZeros = 1;
for (int i = 0; i < mFilter.size(); ++i)
{
if (mFilter.get(i) != (T) (new Integer(0)))
{
++numNonZeros;
T totalValDouble = add(mFilter.get(i), totalVal);
totalVal = totalValDouble;
}
}
Double filteredValDouble = (Double) totalVal / new Double(numNonZeros);
filteredVal = (T) filteredValDouble;
mFilteredValue = filteredVal;
return filteredVal;
}
public T getFilteredValue()
{
return mFilteredValue;
}
public List<T> getFilterStream()
{
return mFilter;
}
public T getUnfilteredValue()
{
return mUnfilteredValue;
}
public void push(T currentVal)
{
mFilter.add(0, currentVal);
if (mFilter.size() > mSize)
mFilter.remove(mFilter.size() - 1);
}
public void resizeFilter(int newSize)
{
if (mSize > newSize)
{
int numItemsToRemove = mSize - newSize;
for (int i = 0; i < numItemsToRemove; ++i)
{
mFilter.remove(mFilter.size() - 1);
}
}
}
}
我可以包括抽象的Add方法吗?如果是,我应该如何正确地扩展类以覆盖原始类型(例如Float,Double,Integer等)?
谢谢
克里斯
编辑:
抱歉,不清楚。恐怕这不是家庭作业,那些日子已经过去很久了。我对Java很陌生,它具有C ++背景(因此,很容易想到运算符重载)。至于“推”方法。我为其中的add方法道歉,那只是在列表中添加一个值,而不是我所指的变量添加(然后记下更改我的方法的名称!)。该类用于提供一个接口,以构造指定长度的列表,用变量填充该列表,并获取最后一个“ x”帧的平均值,以消除数据中的任何尖峰。将新项目添加到FilterData对象时,会将其添加到List的开头,并删除最后一个对象(前提是List已达到允许的最大大小)。因此,要提供连续的移动平均值,我必须对List中的值进行求和和除法。
但是,要执行此添加操作,我将必须找到一种将对象添加在一起的方法。 (它只是一个帮助器类,因此我想使其尽可能通用。)这样更清楚了吗? (我知道代码非常像米老鼠,但我想使其尽可能清晰和简单)。
最佳答案
您想要做的是创建一个Queue
个Number对象,该对象具有固定的大小,要在其上计算平均值。在琐碎的情况下,您的大小= 2并存储两个整数1
和2
,您的平均值为1.5
,因此将过滤器方法的返回类型设置为double是合理的。
然后,您可以编写与此类似的代码
public abstract class FilterData<T extends Number> {
private final Queue<T> mFilter = new LinkedList<T>();
protected Integer mSize;
public FilterData() {
this(10);
}
public FilterData(int size) {
mSize = size;
}
public double filter(T currentVal) {
push(currentVal);
double totalVal = 0d;
int numNonZeros = 0;
for (T value : mFilter) {
if (value.doubleValue() != 0) {
++numNonZeros;
totalVal += value.doubleValue();
}
}
return totalVal / numNonZeros;
}
public void push(T currentVal) {
mFilter.add(currentVal);
if (mFilter.size() > mSize)
mFilter.remove();
}
public void resizeFilter(int newSize) {
if (mSize > newSize) {
int numItemsToRemove = mSize - newSize;
for (int i = 0; i < numItemsToRemove; ++i) {
mFilter.remove();
}
}
mSize = newSize;
}
}
您应该注意,这不是线程安全的。