我想用这个类来计算平均值:
public static class AverageValue<T extends Number> {
T data = 0; //ERROR: incompatible types: int cannot be converted to T
int count = 0;
public AverageValue() {}
public AverageValue(T data) {
this.data = data;
count = 1;
}
public void add(T num) {
data+=num; //ERROR: bad operand types for binary operator '+'
count++;
}
public T average() {
return data/(T)count; //ERROR: incompatible types: int cannot be converted to T
}
}
如果不抽象数,我真的没有得到为什么我们有接口号码。因为这就是接口所做的事情 - 用数据抽象操作而不保留数据本身。
以上也清楚地表明,你可能无法自己编号实现(例如,对于一些非常怪异的实验性数学程序,数字的大小和精度都无限制。)
我尝试使用Number
代替通用T
,结果非常相似。唯一的区别是Number x = 0
实际上是有效的。
有没有办法欺骗java编译这个或者我必须是一个“专业”java程序员并使用双精度来计算字节数组的平均值?
答案 0 :(得分:4)
为了存储和转换表示,如果它没有抽象数字
,我真的没有得到为什么我们有接口Number
interface Number
确实抽象了数字。它不会为了进行计算而抽象数字,因为结果表示的类型没有很好地定义。
以上也清楚地表明,你可能无法自己编号实现(例如,对于一些非常怪异的实验性数学程序,数字的大小和精度都无限制。)
BigDecimal
没有任何问题。
Number x = 0
实际上是有效的。
将Integer
分配给Number
即可。将Integer
分配给扩展Number
(例如Double
)的内容并不正常。这就是为什么会有所不同。
有没有办法诱骗java编译这个或者我必须完全
延迟专业的Java程序员并使用双精度来计算字节数组的平均值?
计算平均值时,需要指定所需的结果表示。你可以自己抽象出来并提供“averager”ingerface,但是关于所需表示的信息需要以某种方式进入方法:
interface AverageMaker<T extends Number> {
T initialResult();
T add(T a, Number b);
T divideByCount(T a, int b);
}
public static <T extends Number, R extends Number> R averageValue(Iterable<T> items, AverageMaker<R> maker) {
R res = maker.initialResult();
int count = 0;
for (T val : items) {
res = maker.add(res, val);
count++;
}
return maker.divideByCount(res, count);
}
定义几个普通制造商,如下:
static final AverageMaker<Double> doubleAvg = new AverageMaker<Double>() {
public Double initialResult() { return 0.0; }
public Double add(Double a, Number b) { return a + b.doubleValue(); }
public Double divideByCount(Double a, int b) { return a/b; }
};
static final AverageMaker<Integer> intAvg = new AverageMaker<Integer>() {
public Integer initialResult() { return 0; }
public Integer add(Integer a, Number b) { return a + b.intValue(); }
public Integer divideByCount(Integer a, int b) { return a/b; }
};
现在,您可以在代码中使用它们和averageValue
方法:
List<Integer> a = new ArrayList<Integer>();
a.add(4);
a.add(8);
a.add(91);
a.add(18);
double avgDouble = averageValue(a, doubleAvg);
int avgInt = averageValue(a, intAvg);
System.out.println(avgDouble); // Prints 30.25
System.out.println(avgInt); // Prints 30
答案 1 :(得分:1)
您正在混合类(Number
)和基本类型(int
)。数字类不支持+
或\
等运算符(字符串支持+
,但这是一种特殊情况;与C#
不同,Java不支持自定义运算符重载)。
BigDecimal
类实际上支持“一些真正奇怪的实验性数学程序具有无限大小和精度的数字”,这表明您(以及如何)确实可以拥有自己的Number
实现
答案 2 :(得分:1)
您可以在课堂上使用double
。由于Integers
的平均值为Double
,因此这应该是正确的。
public class AverageValue<T extends Number> {
double data = 0;
int count = 0;
public AverageValue() {
}
public AverageValue(T data) {
this.data = data.doubleValue();
count = 1;
}
public void add(T num) {
data += num.doubleValue();
count++;
}
public double average() {
return data / count;
}
}
这个编译。用法:
AverageValue<Integer> avgInt = new AverageValue<>();
avgInt.add(1);
avgInt.add(2);
avgInt.add(3);
avgInt.add(4);
System.out.println(avgInt.average());
AverageValue<Double> avgDouble = new AverageValue<>();
avgDouble.add(1.1);
avgDouble.add(1.2);
avgDouble.add(1.3);
avgDouble.add(1.4);
System.out.println(avgDouble.average());
输出:
2.5
1.25
答案 3 :(得分:0)
错误:不兼容的类型:int无法转换为T
var today, someday, text; today = new Date(); someday = new Date(); someday.setFullYear(2100, 0, 14);
if (someday > today) {
text = "Today is before January 14, 2100."; } else {
text = "Today is after January 14, 2100."; } document.getElementById("demo").innerHTML = text;
java中的错误:二元运算符的错误操作数类型&#39; +&#39;
错误:不兼容的类型:int无法转换为T