tony danza
tony danza

Reputation: 306

Cant modify ArrayList elements

I am creating a database of articles written by more than one authors, so I have two classes: Author and Article. The constructor for Article is

        Article(String title, String venue, Author[] authors, long year).

An Author object contains a String with the name of the author and an ArrayList of articles he has written.

So, I have an array of Articles, and I'm trying to create an ArrayList of Authors and add all the articles they have written.

This is my code:

for(int i=0; i<allarticles.length; i++) {
            Author[] tempauthors = allarticles[i].getAuthors();
            for (int j=0; j<tempauthors.length; j++) {
                Author tempauthor = tempauthors[j];
                if (authors.contains(tempauthor)) {
                    Author oldAuthor = authors.get(authors.indexOf(tempauthor));
                    if (!oldAuthor.hasArticle(allarticles[i]))
                        oldAuthor.addArticle(allarticles[i]);
                } else {
                    if (!tempauthor.hasArticle(allarticles[i]))
                        tempauthor.addArticle(allarticles[i]);
                    authors.add(tempauthor);
                }
            }
        }

and here's the hasArticle method: public boolean hasArticle(Article a) { return articles.contains(a); }

I modified the equals method as suggested but now the problem is that I get authors with the right amount of articles but the first one is duplicated. What I am doing wrong? Should I ovverride the Article.equals() method as well?

Upvotes: 0

Views: 252

Answers (2)

Julie in Austin
Julie in Austin

Reputation: 1003

Unless the Author class has its own mechanism for returning the same Author object for each instance of an Author object where the name is the same, the code is working correctly.

The contains() method doesn't "know" that you're referring to an author by name, it only knows that you've asked if the specific Author object is in the ArrayList.

The contains() method compares the entire object using its equals(Object a) method. Two different objects are equal, if and only if, the equals() methods says they are. For a class without an explicit equals() method (other than the one inherited from Object or another class your class extends), the address (pointer ...) is used.

So, you have to define what "equals()" means. In your case, two objects are equal if the name of the authors are equal. In your case, that means equals() is this method --

public boolean equals(Object a) {
  if (! (a instanceof Author))
    return false;

  return this.getname().equals(((Author) a).getname());
}

You also seem to have some funky logic in your code. You want to add the new article to the existing articles the author has. So you need to find the existing entry for that author (indexOf() method in ArrayList), get that entry (get() method ...) then add the article to the Author object already in the ArrayList.

To do this, you'll need to do

Author oldAuthor = authors.get(authors.indexOf(tempauthor));
oldAuthor.addArticle(allarticles[i]);

instead of the remove / addArticle / remove code you have.

You will also need to make sure that you aren't adding an article to the author's list of articles that you've already added.

Upvotes: 2

SLaks
SLaks

Reputation: 887449

You need to override Author.equals() to return true for different but equivalent Author instances.

Upvotes: 2

Related Questions