I am trying to make a priority Queue which contains pair of double and integer types but I am getting this error :
-> 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
Here is the relevant code
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;
}
}
CodePudding user response:
The fundamental problem is that you need a Comparator
, which must return an int
, but subtraction between two double
values returns a double
. Java requires you to be specific here, because a return type of double
doesn't conform, and Java will not coerce this automatically: a cast is required.
However, a double
has a far larger range than int
. So, for a very large or very small difference, the result will be wrong due to overflow or underflow.
Instead, in general, use Double.compare
as your comparator for double
values. In your case, as you're extracting values from an object, use Comparator.comparingDouble(pair -> pair.ratio)
.
As an aside, even when comparing int
values, it is better to not use subtraction, but instead use Integer.compare
(or Comparator.comparingInt
), because large differences (greater than Integer.MAX_VALUE
) can still cause overflow, yielding the wrong result.
CodePudding user response:
The parameter for the PriorityQueue
constructor should be a 2 argument comparison function that returns an int
. But the lambda you supplied returns p2.ratio - p1.ratio
which is a double
... since ratio
has been declared as double
. A conversion from a double
to an int
is a lossy conversion: see the error message!
Therefore you need to perform an explicit cast. Try this instead.
(p1, p2) -> (int)(p2.ratio - p1.ratio)