Reputation: 2612
Say I have these two ArrayLists:
ArrayList<Book> book = new ArrayList<>();
ArrayList<Journal> journal = new ArrayList<>();
Book
and Journal
are two different classes.
Both Book
and Journal
objects have a getYear()
method. I want to make a method that passes in an unknown ArrayList type and compares a passed in year to an object in the list. The following code is in main:
public static void fooBar(int year, ArrayList<?> list)
{
if(list.get(0).getYear() == year) // does not work!
{
}
}
If an unknown type is passed into the method, I cannot use that object's methods (getYear()
). How can I do this without making two methods that do the same thing (one for Book
and one for Journal
)?
Upvotes: 9
Views: 3084
Reputation: 7179
Everyone discussed about the right way of doing it, such as associating your object with a super class containing your desired method, but if you want some fancy implementation without using super class, you can try lambda expression:
ArrayList<Book> book = new ArrayList<>();
book.stream().limit(1).filter(s->s.getYear()==year).forEach(yourcode)
I know this is not what you wanted but you have right solution from other comments.
Upvotes: 1
Reputation: 2108
Have both Book
and Journal
extend a common superclass (Publication
perhaps?) or implement a common interface which defines the getYear()
method:
public abstract class Publication {
private int year;
public int getYear() {
return year;
}
public Publication(int year) {
this.year = year;
}
}
If you then change your Book
and Journal
class declarations and constructors:
public class Book extends Publication {
public Book(int year, ...) {
super(year);
...
}
public class Journal extends Publication {
public Journal(int year, ...) {
super(year);
...
}
You could then pass around a list of Publication
objects:
public void fooBar(int year, List<? extends Publication> list) { ... }
Because it's Publication
that defines the getYear()
method, you can freely use it on objects contained within list
.
Upvotes: 3
Reputation: 2773
Like JonK said, if they share a superclass or interface that defines getYear() then this will be made easier. Actually, the have to have either of those two relationships to make your proposed relationship.
interface HasYear {
public int getYear();
}
Book.java
public class Book implements HasYear{
//...
public int getYear(){/*YOUR IMPLEMENTATION*/}
}
Journal.java
public class Journal implements HasYear{
//...
public int getYear(){/*YOUR IMPLEMENTATION*/}
}
Now, you can create and use your ArrayList like this:
public static void fooBar(int year, ArrayList<? extends HasYear> list){
if(list.get(0).getYear() == year){
//yay
}
}
Upvotes: 4
Reputation: 178253
You can make an interface (if it doesn't already exist) (possibly named HasYear
) that declares the getYear()
method, and have Book
and Journal
implement it.
Then you can have your fooBar
method take an ArrayList
of some type parameter that is a HasYear
.
public static void fooBar(int year, ArrayList<? extends HasYear> list)
The ? extends
is due to the fact it's a consumer and not a producer.
Upvotes: 14