prog.java:59:错误:不兼容的类型:lambda 表达式中的错误返回类型((p1,p2)->(p2.ratio-p1.ratio));



我试图使一个优先级队列包含一对双精度和整数类型,但我得到这个错误:

-> error: incompatible types: bad return type in lambda expression PriorityQueue pq = new PriorityQueue
((p1,p2)->(p2.ratio-p1.ratio));
^
possible lossy conversion from double to int Note: Some messages have been simplified;
recompile with -Xdiags: verbose to get full output 1 error

以下是相关代码

class Item {
int value, weight;
Item(int x, int y){
this.value = x;
this.weight = y;
}
}
class Solution
{
static class Pair {
double ratio;
int index;
Pair(double rat, int ind){
this.ratio = rat;
this.index = ind;
}
}
//Function to get the maximum total value in the knapsack.
double fractionalKnapsack(int W, Item arr[], int n) 
{
// Your code here
PriorityQueue<Pair> pq = new PriorityQueue<Pair>
((p1,p2)->(p2.ratio-p1.ratio));

for(int i=0; i<n; i++){
double x = (arr[i].value*1.0)/(arr[i].weight*1.0);
pq.add(new Pair(x,i));
}
int s=0;
double ans=0;
while(!pq.isEmpty()){
Pair pair = pq.poll();
if(s+arr[pair.index].weight<W){
ans+=arr[pair.index].value;
s+=arr[pair.index].weight;
}else{
double y = (W-s)*1.0;
ans+= y*pair.ratio;
break;
}
}
return ans;
}
}

基本问题是您需要一个Comparator,它必须返回一个int,但是两个double值之间的减法返回一个double。Java要求您在这里指定,因为返回类型double不符合,Java不会自动强制执行:需要强制转换。

然而,double的范围比int大得多。因此,对于非常大或非常小的差异,由于溢出或下溢,结果将是错误的。

相反,通常使用Double.compare作为double值的比较器。在您的示例中,当您从对象中提取值时,请使用Comparator.comparingDouble(pair -> pair.ratio)

作为题外话,即使在比较int值时,最好不要使用减法,而是使用Integer.compare(或Comparator.comparingInt),因为较大的差异(大于Integer.MAX_VALUE)仍然会导致溢出,从而产生错误的结果。

PriorityQueue构造函数的形参应该是一个返回int的2参数比较函数。但是您提供的lambda返回p2.ratio - p1.ratio,这是double…因为ratio已被声明为double。从doubleint的转换是有损转换:请参阅错误消息!

为了满足编译器的要求,你需要执行显式强制转换;例如

(p1, p2) -> (int)(p2.ratio - p1.ratio)

然而,虽然这解决了编译错误,但它不是一个正确的解决方案。在某些情况下,它会给出错误的答案。具体来说,如果0.01.0exclusive之间的比率差异,则窄化强制转换将截断该值为0…它错误地认为比率相等

见Mark给出的正确答案

最新更新