在不知道java

时间:2017-06-29 13:40:43

标签: java

我在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多个类,它会生成代码很长很难维护。

有人可以为此建议解决方案吗?提前谢谢!

4 个答案:

答案 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()方法,在BookMovie中实现(覆盖)。

然后,您的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)

放置不同的不相关类型的对象,例如BookMovie,这些对象没有共同的超类(除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方法实际返回标题,这会使您的程序真正令人困惑。