我在java中有两个类:Movie和Book(它是一个简化的例子):
图书可以有作者:
public class Book {
public String author;
public Book(String a) {
this.author = a;
}
public String getAuthor(){
return author;
}
}
电影可以有标题:
public class Movie {
public String title;
public Movie(String t) {
this.title = t;
}
public String getAuthor(){
return title;
}
}
我试图将所有对象放在这样的列表中:
ArrayList myList = new ArrayList();
Book book = new Book("William");
Movie movie = new Movie("Titanic");
myList.add(book);
myList.add(movie);
之后我想算一下约翰所写的书数(或任何其他特定的标题)。但是我不能应用getAuthor()或getTitle()方法,因为java不知道它是什么类型的对象
int counter = 0;
for (int i =0;i<myList.size();i++){
if (myList.get(i).getAuthor().equals("John") ){
counter +=1;
}
我可以使用if子句,每次检查一个对象类型,并为不同的对象应用不同的方法,但这是不可行的,因为在现实生活中我有20多个类,它会生成代码很长很难维护。
有人可以为此建议解决方案吗?提前谢谢!
答案 0 :(得分:6)
创建一个界面
public interface HasAuthor {
String getAuthor();
}
在你的两个类中实现这个接口并使用它:
List<HasAuthor> list = new ArrayList<>();
list.add(new Book());
list.add(new Movie());
long count = list.stream().filter(smth -> "John".equals(smth.getAuthor())).count();
答案 1 :(得分:2)
2017年你无法使用ArrayList myList = new ArrayList();
。世界已经从那种过时且容易出错的编程风格转移。泛型在2004年被添加到Java编程语言中,从那时起,任何使用没有泛型类型参数的泛型类的尝试都会发出警告。这让我想到了下一期:
你不能在2017年忽视警告。实际上,从来没有一个时间忽视警告。当您尝试ArrayList myList = new ArrayList();
注意它们时,您的IDE应该发出警告。
所以,最重要的是,你不应该把书和电影放在同一个集合中。如果你有一个有一个作者的书类,一个有导演的电影类,(我会忽略你的电影有一个标题并将其作为“作者”返回的例子,因为它是荒谬的),那么你可以拥有一个名为Item
的接口或抽象基类,使用String getAuthor()
方法,在Book
和Movie
中实现(覆盖)。
然后,您的myList
将是ArrayList<Item>
,并且由于Item
采用getAuthor()
方法,您将可以执行myList.get( 0 ).getAuthor()
无需知道它是书还是电影。
答案 2 :(得分:0)
首先,myList.get(i).getAuthor() == "John"
无法工作,因为需要通过equals()
比较字符串(查找有关原因的教程)。
其次,您需要知道对象的类型并进行相应的转换才能调用方法(您可以不使用反射进行投射,但请不要在家中尝试)。因此,当迭代您的列表时,您需要检查:
for (Object o : myList ) {
if (o instanceof Book && ((Book)o).getAuthor().equals("John") ){
counter +=1;
}
}
但是,如果您希望一个列表包含所有书籍和电影,您最好提供一个通用界面或超类:
//Make it abstract to not allow instances of this class directly
abstract class PieceOfArt {
private String creator;
public String getCreator() {
return creator;
}
}
class Book extends PieceOfArt {
//Access the creator as the author
//note that I do this just for demonstration purposes, just using getCreator() would be perfectly fine
public String getAuthor() {
return getCreator();
}
}
class Movie extends PieceOfArt {
//Access the creator as the director
//note that I do this just for demonstration purposes, just using getCreator() would be perfectly fine
public String getDirector() {
return getCreator();
}
}
List<PieceOfArt> myList = ...;
for( PieceOfArt p : myList ) {
if( p.getCreator().equals("John") {
...
}
}
答案 3 :(得分:0)
放置不同的不相关类型的对象,例如Book
和Movie
,这些对象没有共同的超类(除java.lang.Object
之外)是不好的做法。
您可以为这些类型定义一个公共抽象超类,然后创建该类型的List
。例如:
public abstract class Product {
private String title;
private String author;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
class Book extends Product {
}
class Movie extends Product {
}
创建一个List<Product>
并使用它:
List<Product> products = new ArrayList<>();
Book book = new Book();
book.setTitle("Cooking");
book.setAuthor("Bob the Cook");
products.add(book);
Movie movie = new Movie();
movie.setTitle("Romance at sea");
movie.setAuthor("John");
products.add(movie);
int count = 0;
for (Product product : products) {
if (product.getAuthor().equals("John")) {
count++;
}
}
注意:在getAuthor
的情况下,不要让Movie
方法实际返回标题,这会使您的程序真正令人困惑。