Classe de conteneur java


J'ai un problème et je ne comprends pas comment le résoudre.

J'ai donc 3 classes: la première est principale, la seconde est livre et la troisième est une étagère qui contient des livres.

Classe de livre

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;
}

Classe Principale

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());
    }

Classe d'étagère

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");
}

Comment puis-je faire la méthode append dans la classe shelf? Évidemment, cela me donne NullPointerException car le tableau que j'utilise est null, mais je ne sais pas comment le gérer.

Une autre question, comment puis-je insérer des objets de livre dans la classe Étagère?

Au début dans le constructeur, j'ai écrit " ceci.v = v " donc, quand j'ai déclaré un objet étagère, j'ai passé son tableau v dans la classe principale, qui n'est pas null, cela a fonctionné mais l'exercice a dit de ne pas faire comme ça.

PS Je dois faire cet exercice avec un tableau normal, je veux dire sans arrayList, je dois encore l'apprendre.

Author: PM 77-1, 2015-12-01

3 answers

Le problème se trouve dans votre constructeur Shelf.

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

Vous initialisez le tableau à la taille 3, mais vous ne le remplissez jamais avec des livres dans le constructeur. Donc, une fois que vous avez fait new Shelf(), il a un tableau de livres de taille 3 avec 3 valeurs null dedans.

Donc, vous obtenez un NPE parce que votre méthode append(Book x) suppose qu'il n'y a pas de valeurs null dans votre tableau de livres.

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;
}

Pour résoudre le problème: Le moyen le plus simple est de changer votre constructeur pour créer un tableau de taille 0. Ensuite, le reste de votre code le gérera.

public Shelf()
{
    v = new Book[0];
}
 1
Author: Andy Guibert, 2015-12-01 00:44:17

En ce moment, vous développez et copiez chaque fois qu'un nouveau livre est inséré. Ce n'est pas vraiment nécessaire. Le mieux est d'avoir une capacité initiale qui est développée uniquement lorsque le tableau est rempli.

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;
    }
}

Cela a un avantage en termes de performances, mais il me semble également que votre intention est plus claire en divisant le code d'extension du code d'ajout. Avoir une méthode distincte signifie qu'elle peut également être appelée dans votre méthode insert.

Vous pouvez réduire le code d'extension en utilisant Arrays méthodes mais je suppose que le fait que vous ne puissiez pas utiliser les collections Java implique que vous devez le faire manuellement.

Vous avez également demandé comment insérer; j'ai ajouté un exemple de méthode pour cela. La chose clé à retenir est que vous devez d'abord déplacer les livres après la position d'insertion de la fin. Sinon, vous finirez par copier le même livre à travers le reste du tableau.

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++;
}
 2
Author: sprinter, 2015-12-01 01:25:15

Vous pouvez utiliser quelque chose comme ceci:

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");
    }
 0
Author: Viacheslav Vedenin, 2015-12-01 00:00:07