Reputation: 1246
I've got an Object called Price
, that describes the selling and buying behaviour of an item. Next to some other properties it looks mainly like this:
public class Price {
private PriceType type;
private int amount;
private ItemData itemData;
//...
}
with respective getters and setters. amount
is the amount of this item that shall be sold/bought, and ItemData describes the specifications of the item. PriceType is an Enum, that's either PriceType.SELLING
or PriceType.BUYING
.
I now have a method, which job it is, to find the best matching Price in a list. All my Prices are stored in a list simply called pricesList
. Until now, my method just went through the list, and returned the first Price
that matched the PriceType
and the ItemData
:
public static Price getPriceByBiggestBaseAmountMatchingGivenAmount(
ItemData dataOfCollected, PriceType priceType, int amount) {
return pricesList
.stream()
.filter(p ->
p.getItemData().equals(dataOfCollected) &&
p.getType().equals(priceType))
.findFirst().orElse(null);
}
However this completely ignores the fact that there is a minimal amount that must be respected. So, what I need is that it does not just find me the first Price
that somehow matches the ItemData
and the PriceType
, but it should also take account the minimal amount. It should ignore every Price
that has an amount smaller than the given amount, and of all the remaining ones, it should return the one with the biggest price.getAmount()
. This might be a bit hard to understand so here's an example:
Say I have three Price-Objects of the same PriceType and ItemData, so they all describe, lets say a PriceType.BUYING
price - ergo the price my program will pay for a given amount of this item.
price1.getAmount() == 1 //So this is describing the price for a single item.
price2.getAmount() == 6 //So this is describing the price for half a dozen of the item.
price3.getAmount() == 64 //Describing the price for an entire stack of the item.
If I do getPriceByBiggestBaseAmountMatchingGivenAmount(data, type, x)
for some x
es this shall be returned:
x: 1 => price1
x: 3 => price1
x: 7 => price2
x: 63 => price2
x: 64 => price3
x: 120 => price3
x: -1 => null
I have no idea how to achieve that with a stream, of course I could do it with a for loop, but that's something I'd only do as a last resort...
Upvotes: 1
Views: 2560
Reputation: 46
Try it this way: First filtering out all prices that are smaller than the desired amount and then taking the biggest value out of the list with max().
public static Price getPriceByBiggestBaseAmountMatchingGivenAmount(
ItemData dataOfCollected, PriceType priceType, int amount) {
return pricesList
.stream()
.filter(p ->
p.getItemData().equals(dataOfCollected) &&
p.getType().equals(priceType) &&
p.getAmount() <= amount) // remove bigger amounts
.max(Comparator.comparing(Price::getAmount)) // take the biggest
.orElse(null);
}
Upvotes: 3