Java中的通用算术 [英] Generic Arithmetic in Java

查看:161
本文介绍了Java中的通用算术的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个过滤器类,其中用户必须声明类型(例如 Filter< Double> Filter< Float>

  public abstract class FilterData< T> 
{
private final List< T> MFILTER;
private T mFilteredValue; //当前过滤值
保护整数mSize = 10;
private T mUnfilteredValue; //当前未过滤的值
$ b $ 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); (mFilter.size()> mSize)
mFilter.remove(mFilter.size() - 1);
}

public void resizeFilter(int newSize)
{
if(mSize> newSize)
{
int numItemsToRemove = mSize - 新尺寸;
for(int i = 0; i< numItemsToRemove; ++ i)
{
mFilter.remove(mFilter.size() - 1);
}
}
}
}

上午我有权利包括抽象的Add方法,如果是这样,我应该如何正确地扩展这个类来覆盖原始类型(例如Float,Double,Integer等)
感谢
Chris



编辑:

不清楚的道歉。这不是我害怕的功课,那些日子在我身后很久。我对Java来说很陌生,来自C ++背景(因此容易出现操作符重载)。至于推的方法。我为那里的add方法表示歉意,那就是简单地向列表中添加一个值,而不是我所指的变量添加(做一个注释来改变我的方法的名称!)。该类用于提供一个接口来构造指定长度的列表,使用变量填充该列表,并获取最后'x'帧的平均值以消除数据中的任何尖峰。当一个新项目被添加到FilterData对象中时,它将被添加到List的开头,并且最后一个对象被移除(前提是List已达到允许的最大大小)。因此,为了提供连续的移动平均线,我必须对列表中的值进行总结和划分。
但是,为了执行这个添加,我将不得不找到一种将对象添加在一起的方法。 (它只是一个帮助类,所以我想尽可能通用)。这是否使它更清晰? (我知道这个代码非常适合米老鼠,但我希望尽可能简洁明了)。

解决方案

您要做的是创建一个 Queue 的数字对象,其中您需要计算平均值的固定大小。通过size = 2的简单情况并存储两个整数 1 & 2 你的平均值为 1.5 ,所以可以合理的将你的过滤方法的返回类型设置为double。



然后您可以编写类似于此的代码

  public abstract class FilterData< ; T扩展数字> {
private final Queue< T> mFilter = new LinkedList< T>();
保护整数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;




$ b你应该注意到这不是线程安全的。

I have a filter class wherein the user must declare the type (e.g. Filter<Double>, Filter<Float> etc). The class then implements a moving average filter so objects within the class must be added. My question is how to do this? I'm sorry if the answer is simple but I've muddled myself up by thinking about it too much I think :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);
        }
    }
}
}

Am I right to include the abstract Add method and if so, how should I extend the class correctly to cover primitive types (e.g. Float, Double, Integer etc.) Thanks Chris

EDIT:

Apologies for being unclear. This is not homework I'm afraid, those days are long behind me. I'm quite new to Java having come from a C++ background (hence the expectation of easy operator overloading). As for the "push" method. I apologise for the add method in there, that is simply add a value to a list, not the variable addition I was referring to (made a note to change the name of my method then!). The class is used to provide an interface to construct a List of a specified length, populate it with variables and obtain an average over the last 'x' frames to iron out any spikes in the data. When a new item is added to the FilterData object, it is added to the beginning of the List and the last object is removed (provided the List has reached the maximum allowed size). So, to provide a continual moving average, I must summate and divide the values in the List. However, to perform this addition, I will have to find a way to add the objects together. (It is merely a helper class so I want to make it as generic as possible). Does that make it any clearer? (I'm aware the code is very Mickey Mouse but I wanted to make it as clear and simple as possible).

解决方案

What you're trying to do is create a Queue of Number objects with a fixed size, over which you want to calculate an average. With the trivial situation that you have size = 2 and store two integers 1 & 2 you have an average of 1.5 so its reasonable to set the return type of your filter method to double.

You can then write this code similar to this

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;
    }
}

You should note that this isn't thread safe.

这篇关于Java中的通用算术的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆