So the problem you've come across is that you're not typing your list, creating a new ArrayList() without specifying a type is functionally the same as creating a new ArrayList<Object>(). When you then call the items from within this list, you will have an Object returned, which doesn't have the price attribute
With an implementation of streams you find a fairly simple solution to this problem:
double minFruitPrice = Stream.of(f1, f2, f3)
.reduce((acc, val) -> acc.price < val.price ? acc : val)
.orElseThrow(() -> new RuntimeException("No fruits provided!")) // reduce with 1 argument returns an optional
.getPrice(); // Always use a getter
The "correct" implementation in this case though, is to create an object with a price attribute:
abstract class PricedObject {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Then create your Fruit and Ball objects which will extend that class (taking on its attributes)
class Fruit extends PricedObject {
private String type;
private String colour;
private String season;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public String getSeason() {
return season;
}
public void setSeason(String season) {
this.season = season;
}
}
And
class Ball extends PricedObject {
private String colour;
private String pattern;
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public String getPattern() {
return pattern;
}
public void setPattern(String pattern) {
this.pattern = pattern;
}
}
Then use those objects inside the streams implementation given above:
Stream.of(f1, f2, f3, b1, b2, b3)
.reduce((acc, val) -> acc.getPrice() < val.getPrice() ? acc : val);
Which will return an Optional of the PricedItem with the lowest price. You can then call .get() to get the value from the optional, although it's safer to use one of the orElse options.
FruitandBallwhich you could callPricedItemwhich has a proeprtyprice, whichFruitandBallthen extend from. /e or as mentioned by @khelwood an interface might be nicer, especially if you have other classes you need to extend from.getPrice()method, and have all your priceable classes implement it. Then store them in anArrayList<Priceable>.instanceofwhich class the object refers to and then just determine the lowest valueinstanceofhere would work but I would consider it to smell quite badly to be honest...