容器 class java

Container class java

我有一个问题,我不知道如何解决。

所以我有 3 个 classes:第一个是主要的,第二个是书,第三个是包含一些书的书架。

图书class

public class Book {
private String title;
private int year;
private String edition;

public Book(String title, int year, String edition) {
    this.title= title;
    this.year= year;
    this.edition = edition;
}

public Book(Book l)
{
    this.title = l.title;
    this.year = l.year;
    this.edition = l.edition;
}

主要class

public static void main(String[] args) {


    Book one = new Book("Title1", first, 2014, "Edition1");
    Book two = new Book("Title2", second, 2013, "Edition2");
    Book three= new Book("Title3", third, 2015, "Edition3");
    Book four = new Book("Title4", fourth, 2015, "Edition4");

    Book[] v = new Book[3];
    v[0] = one;
    v[1] = two;
    v[2] = three;


    Shelf shelf= new Shelf();

   try{

    shelf.append(four);
   }(catch myException e)
    {
       System.out.println(e.toString());
    }

货架class

public class Shelf {
private Book[] v;

public Shelf() 
{
    v = new Book[3];
}

public void append (Book x) throws myException
{
   if(x != null && v != null)
   {
    Book[] vAppend = new Book[v.length+1];

    for(int i=0; i<v.length; i++)  
    {
        vAppend[i] = new Book(v[i]);
    }
    vAppend[v.length] = new Book(x);
    v = vAppend;

   }
    throw new myException("Null");
}

如何在 shelf class 中执行追加方法?显然它给了我 NullPointerException 因为我正在使用的数组是空的,但我不知道如何管理它。

还有一个问题,如何在 Shelf 中插入 Book 对象 class?

起初我在构造函数中写了“this.v = v”,所以当我声明一个 shelf 对象时,我在 main class 中传递了它的 v 数组,它不是空的,它工作但是练习说不要这样做。

P.S。我必须用普通数组做这个练习,我的意思是没有arrayList,我仍然需要学习它。

你可以使用这样的东西:

public class Shelf {
    private Book[] v;

    public Shelf()
    {
        v = new Book[0];
    }

    public Shelf append (Book x) throws myException
    {
        if(x != null)
        {
            v = Arrays.copyOf(v, v.length + 1);
            v[v.length] = new Book(x);
            return this;
        }
        throw new myException("Null");
    }

问题出在您的 Shelf 构造函数中。

public Shelf()
{
    v = new Book[3];
}

您正在将数组初始化为大小 3,但您从未在构造函数中用书籍填充它。所以一旦你这样做 new Shelf() 它有一个大小为 3 的 Book 数组,其中有 3 个空值。

因此,您得到了一个 NPE,因为您的 append(Book x) 方法假设您的 Book 数组中没有空值。

public void append(Book x)
{
    Book[] vAppend = new Book[v.length + 1];

    for (int i = 0; i < v.length; i++)
    {
        // ERROR: v.length is 3 but 
        // v[0], v[1], and v[2] will be null initially!!
        vAppend[i] = new Book(v[i]);
    }
    vAppend[v.length] = new Book(x);
    v = vAppend;
}

解决问题: 最简单的方法是更改​​您的构造函数以生成大小为 0 的数组。然后您的其余代码将处理它。

public Shelf()
{
    v = new Book[0];
}

目前每插入一本新书,您都在扩展和复制。这不是真的必要。更好的是有一个初始容量,只有当数组被填充时才扩展。

private static final int INCREMENT = 100;
private int capacity = 0;
private int size = 0;
private Book[] books = {};

public void append(Book book) {
    assert book != null;
    expandIfFull();
    books[size++] = book;
}

private void expandIfFull() {
    assert size <= capacity; 
    if (capacity == size) {
        capacity += INCREMENT;
        Book[] copy = new Book[capacity];
        for (int i = 0; i < size; i++)
            copy[i] = books[i];
        books = copy;
    }
}

这具有性能优势,但在我看来,通过将扩展代码与附加代码分开可以使您的意图更加清晰。拥有一个单独的方法意味着它也可以在您的插入方法中调用。

您可以使用 Arrays 方法减少扩展代码,但我假设您不能使用 Java 集合这一事实意味着您需要手动执行此操作。

你还问了怎么插入;我为此添加了一个示例方法。要记住的关键是你需要先从最后移动插入位置之后的书籍。否则,您最终只会在数组的其余部分复制同一本书。

public void insert(int index, Book book) {
    assert index < size;
    expandIfFull();
    for (int i = size; i > index; i--)
        books[i] = books[i - 1];
    books[index] = book;
    size++;
}