Reputation: 29
I have 2 clases named Fruits and Balls. For each of them, one of the attribute is Price. I need to make a static metod that return from an mix aray only the element with the smallest Price. I have the objects f1, f2, f3, b1, b2, b3.
I've made an ArrayList list like this:
{ Fruit f1 = new Fruit("Apple", "Red", "Summer", 9.5);
...
Ball b1 = new Ball("Red", "Stripes", 10.5);
...
ArrayList list = new ArrayList();
list.add(f1);
list.add(b1);
...
}
Now regarding the method I have to make I started like this:
static void method(ArrayList list) {
for (int i = 0; i < lista.size(); i++) {
}
I get stucked in the mix of getting elemets out of the array and the getters used to find the price for each element. Can you help me?
Even if you don t understand what I m trying to do could you help me with some tips of mix arays of different elements. Thank you!
Upvotes: 0
Views: 3762
Reputation: 9
If fruits and balls have a price, you should make both abstract classes and let them implement the Price interface.
For example
public abstract class Fruit implements Price
public abstract class Balls implements Price
with
public interface Price {
double getPrice();
}
Then, you could have an Apple with the price 9.5
public class Apple extends Fruit {
@Override
public double getPrice() {
return 9.5;
}
}
and a RedBall with the price 10.5
public class RedBall extends Ball {
@Override
public double getPrice() {
return 10.5;
}
}
At the end, you are able to define a List of Price elements (item with a price) like this:
Apple apple = new Apple();
RedBall redBall = new RedBall();
ArrayList<Price> items = new ArrayList<Price>();
items.addAll(apple, redBall);
This way, there's no need to mix different elements.
Upvotes: 1
Reputation: 5316
There are few points which you should consider.
So following this guideline let's have a ArrayList containing objects of a specific type. Let's call this type as Item
(simplest name, you can choose more contextual name)
Better make it an Interface. Also as we need to access price so let's have a function(method as we call in Java) named
getPrice()
. The implementing classes Ball and Fruit will implement this method and return price
attribute.
But we need to have Ball and Fruit in the list so let's implement interface Item
by both of these classes.
Our ArrayList will be now be like
ArrayList < Item > list = new ArrayList<>();
This ArrayList is capable of adding object of Ball and Fruit as both of these classes implement the interface Item
Now iterate the ArrayList of type Item and access the getPrice()
and hopefully your job will be done.
Upvotes: 1
Reputation: 1241
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.
Upvotes: 1