我正在尝试制定尽可能通用的方法来在各种类型的值之间进行补间。
因此,给定一个起始值和结束值,例如 Int、Float 或 Double 以及步数 (int),它将返回沿相同类型的这些步均匀分布的值。
但是,我开始怀疑;
a) 我对泛型的了解很糟糕。
b) 这可能是不可能的:(
所以,为了清楚起见,举一个例子;
SpiffyTween<Double> meep = new SpiffyTween<Double>(1d,10d, 100);
while (meep.hasNext()){
Log.info("value="+meep.next());
}
将返回 0.0,0.1,0.2..etc 直至 9.9
但是 SpiffyTween 也可以与其他数字类型一起使用,而无需为每种数字类型单独编写代码。
这是我现在拥有的代码;
class SpiffyTween<T extends Number> implements SpiffyGenericTween<T>
{
static Logger Log = Logger.getLogger("SpiffyTween <Number>");
private T start;
private T end;
int totalsteps=0;
int CurrentStep = 0;
ArrayList<T> steps = new ArrayList<T>();
public SpiffyTween(T start,T end, int steps) {
this.start = start;
this.end = end;
this.totalsteps = steps;
precalculate();
}
private void precalculate() {
//calc step difference
double dif = ((end.doubleValue() -start.doubleValue())/totalsteps);
Log.info("dif="+dif);
int i=0;
while(i<totalsteps){
T stepvalue = (T)((Number)(start.doubleValue() +(dif*i)));
steps.add(stepvalue);
Log.info("add step="+stepvalue);
i++;
}
}
public T next(){
T currentVal = steps.get(CurrentStep);
CurrentStep++;
return currentVal;
}
@Override
public boolean hasNext() {
if (CurrentStep<totalsteps){
return true;
}
return false;
}
}
这有效……差不多。 虽然数字大致正确,但偶尔会出现以下值: 9.600000000000001 或者 2.4000000000000004
我假设这与此处未经检查的类型转换有关;
T stepvalue = (T)((Number)(start.doubleValue() +(dif*i)));
但我不知道如何做得更好。
无论解决方案是什么(如果有的话),我的长期计划是尝试编写类似的代码,也可以处理各种数字类型的数组。因此,您可以通过向其提供开始和结束的 x/y/z 坐标数组来在 3 维点之间进行补间。
此外,可能更相关的是,在此处的代码示例中完成了基本添加。我可能希望其他类型的补间成为可能,这样会使数学更加复杂。 更好的路线是转换为 BigNumber,然后在所有处理完成后(以某种方式)返回到初始 T 吗?
预先感谢您的任何帮助或指示。
最佳答案
您实际上并不需要泛型来编写一次代码。考虑下面的代码。您的练习是扩展到其他维度并确保调用者不会使用少于一步:
补间类
package com.example.stepup;
public class Tween {
public static int[] get1DimSteps (int start, int end, int steps) {
double[] preciseResult = get1DimSteps((double) start, (double) end, steps);
int[] result = new int[steps];
for (int i=0; i<steps; i++) {
result[i] = (int) (preciseResult[i] + 0.5D);
}
return result;
}
public static double[] get1DimSteps (float start, float end, int steps) {
double[] result = get1DimSteps((double)start, (double)end, steps);
return result;
}
public static double[] get1DimSteps (double start, double end, int steps) {
double distance;
double stepSize;
double[] result = new double[steps];
distance = end - start;
stepSize = distance / steps;
for (int i=0; i < steps; i++) {
result[i] = start + stepSize*i;
}
return result;
}
}
StepupTest类
package com.example.stepup;
public class StepupTest {
public static void main(String[] args) {
// get steps from "start" to "finish"
int startI = -1;
int endI =999;
float start = (float) startI;
float end = (float) endI;
double startD = (double) startI;
double endD = (double) endI;
int numberOfSteps = 100;
double[] steps = Tween.get1DimSteps( start, end, numberOfSteps);
double[] stepsD = Tween.get1DimSteps(startD, endD, numberOfSteps);
int[] stepsI = Tween.get1DimSteps(startI, endI, numberOfSteps);
for (int i=0; i < numberOfSteps; i++) {
System.out.println(" " + i + ". " + steps[i] + ", " + stepsD[i] + ", " + stepsI[i]);
}
}
}
关于java - 通用数字补间(帮我做一个奇怪的技巧..),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25476826/