使用数字子类的泛型来创建一个翻转计数器

时间:2013-10-10 17:27:01

标签: java generics subclass

我正在尝试创建一个计数器,只要达到预设的上限就会翻转,并在达到所述上限时重置为其最低值。我已经实现了这个类,它工作得很好。但是,在我的解决方案的路上,我想尝试使用Java Generics。我想尝试扩展我的计数器,这样它不仅使用整数,而且可以使用任何类型的数字。我知道计数器通常只需要使用整数,但我想知道是否可以完成。

我认为代码与下面的代码类似。但是,java.lang.Number没有获取/设置其值的“通用”方法。我是否需要创建自己的数字类才能启用此功能?另外,我知道如果我确实这样做了,我需要改变我的等于检查,以便他们有一个浮点值的错误阈值,这或多或少是我的int计数器的修改版本与我认为适用的泛型。

修改 有人建议我采用映射方法,我存储一个整数计数器并保持一个增量值,这样当我想吐出一个数字时,我只是将当前计数乘以增量值。但是,我不相信这会满足我的确切需求,因为我不希望每次都增加相同的数量。这个计数器的主要焦点更多的是一种固定范围编号的方法,当添加或减去时,它知道如何处理回绕。

我想描述它的最佳方式(尽管可能不正确)就像Integer一样,可以自动处理上溢/下溢。

package com.math;

public class GenericRolloverCounter<T extends Number> {

   private T value;
   private T lowValue;
   private T highValue;

   public GenericRolloverCounter(T l_startValue, T l_highValue) {
      this.lowValue = l_startValue;
      this.highValue = l_highValue;
      this.value = l_startValue;
   }

   public T getValue() {
      return value;
   }

   public void setValue(T value) {
      this.value = value;
   }

   public void increment(T valToIncrementBy) {
      this.value += valToIncrementBy;
      if (this.value > this.highValue) {
         this.value = (this.lowValue + (this.value - (this.highValue + 1)));
      }
   }

   public void increment() {
      this.increment(1);
   }

   public void decrement(T valToDecrementBy) {
      this.value -= valToDecrementBy;
      if (this.value < this.lowValue) {
         this.value = ((this.value + this.highValue + 1) - this.lowValue);
      }
   }

   public void decrement() {
      this.decrement(1);
   }

   @Override
   public String toString() {
      return Integer.toString(this.value);
   }
}

1 个答案:

答案 0 :(得分:0)

您可能还想指定计算的金额。默认值为1

您可以使用Number方法.doubleValue()并进行双重算术来解决其中一些问题。

以下是转换为使用此想法的方法之一。

public void decrement(double valToDecrementBy) {
  double work = this.value.doubleValue();
  work -= valToDecrementBy;
  // should use some value related to incrementing amount
  if ((this.value.doubleValue() - this.lowValue.doubleValue()) < 0.1D) {
     work = ((this.value.doubleValue() + this.highValue.doubleValue() + 1) - this.lowValue.doubleValue());
  }
  // ... no way to put it back
}

但是,仍然没有办法把价值放回去,干净利落。由于'Number'只有一些常用的非抽象子类,你可以做一些丑陋的instanceof内容来存储值。它看起来像这样:

if (theValue instanceof Double) { // depends on it having a non-null value prior
    theValue = (T)(new Double(work));
}

或者您可以在开始时将起始值转换为double并使用双打。

private double value;
private double lowValue;
private double highValue;

public GenericRolloverCounter(T l_startValue, T l_highValue) {
    this.lowValue = l_startValue.doubleValue();
    this.highValue = l_highValue.doubleValue();
    this.value = l_startValue.doubleValue();
}

这确实引入了递增浮点值的问题以及那里的舍入/评估问题。

哦......你的toString()应该是:

return value.toString();

toString()类上使用原生T方法。

@ Crusher的评论提出了另一种方法。将所有内容映射到'int'并保持乘数。这里有一些代码来表明我的意思。 (谢谢破碎机)

private int value;
private int lowValue;
private int highValue;
private double incr;

public GenericRolloverCounter(T l_startValue, T l_highValue, T incrementAmount) {
    double incr = incrementAmount.doubleValue();
    this.lowValue = Math.round(l_startValue.doubleValue() / incr);
    this.highValue = Math.round(l_highValue.doubleValue() / incr);
    this.value = Math.round(l_startValue.doubleValue() / incr);
}

public void increment(int valToIncrementBy) {
  this.value += valToIncrementBy;
  if (this.value > this.highValue) {
     this.value = (this.lowValue + (this.value - (this.highValue + 1)));
  }
}

@Override
public String toString() {
  return String.valueOf(incr * this.value);
}