Im learning Java and having a problem with ArrayList.
Firstly I have a class called Item, with which I create various item objects. Then I have a class Catalogue which is an array list and should hold a list of the item objects I create. At the moment I can manually add the items to the catalogue by invoking an addItem method on the Catalogue object and manually entering the name of the item object I want to add (item1 item2 item3 etc) But I wanted to know if there is a way to add the items to the ArrayList automatically each time I create an item object?
I should mention, my list needs to hold an infinite amount of items, so I have not specified a size 开发者_StackOverflow社区in my code. Any help would be greatly appreciated :) Thanks
import java.util.ArrayList;
public class Catalogue
{
private ArrayList<Item> catalogue;
public Catalogue ()
{
catalogue = new ArrayList<Item>();
}
public void addAnItem(Item item)
{
catalogue.add(item);
}
}
Use the Catalogue
as an Item
factory:
public class Catalogue
{
...
public Item createItem()
{
Item item = new Item();
catalogue.add(item);
return item;
}
...
}
Another approach: Make Catalogue
singleton and let the items add themselves.
One way you could do this, is if you passed the Catalogue into the constructor of the Item class, and once the item is set up, add the item to the catalogue at that point.
It may look something like this
public Item(Catalogue catalogue) {
// set up item here
// finally add item to the catalogue
catalogue.addAnItem(this);
}
I have put some comments at Matten and Codemwnci's answers, and here is an explanation of them.
Codemwnci suggests that you should not be able to construct an Item without setting its catalogue.
public class Item {
public Item(Catalog catalog) {
// set up item here
// finally add item to the catalog
catalog.addAnItem(this);
}
}
This explicit constructor removes the implicit default (no-arg) constructor, and you cannot construct an Item without it having a valid, non-null catalog.
If you have various types of items, with (slightly) different behaviour, you might be better served with Matten's answer (although slightly changed here).
As an example I'm using a Book (which is your Item). My Book has a title, author, textAtTheBack, and weight.
interface Book {
String getTitle();
String getAuthor();
String getTextAtTheBack();
Long getWeight(); // in grams, can be very heavy!
}
public class Catalog {
private ArrayList<Book> catalogue;
public Book createPaperback(final String title, final String author,
final String tatb, final Long weight) {
Book b = new Book() {
String getTitle() { return title; }
String getAuthor() {return author; }
String getTextAtTheBack() {return tatb;}
Long getWeight() {return weight;}
}
catalogue.add(b);
return b;
}
public Book createEBook(final String title, final String author,
final String tatb) {
Book b = new Book() {
String getTitle() { return title; }
String getAuthor() {return author; }
String getTextAtTheBack() {return tatb;}
Long getWeight() {return 0;} // Yep - no weight!
}
catalogue.add(b);
return b;
}
}
Alternatively, you could have different catalogues:
public abstract class Catalogue {
private final List<Book> books = new ArrayList<Book>;
public abstract Book (final String title, final String author,
final String tatb, final Long weight);
/** Find the book with the given title (not null) in the current catalogue.
* @return the book, or null if not found.
*/
public void findBook(String title) {
for (Book b : books) {
if (b.getTitle().equalsIgnoreCase(title)) {
return b;
}
}
return null;
}
protected void addBookToCatalogue(Book b) {
books.add(b);
}
}
public class EbookCatalogue extends Catalogue {
public Book (final String title, final String author,
final String tatb, final Long weight) {
Book b = new Book() {
String getTitle() { return title; }
String getAuthor() {return author; }
String getTextAtTheBack() {return tatb;}
Long getWeight() {return 0;} // ignore weight
}
addBookToCatalogue(b);
return b;
}
}
In the rest of the program you can have multiple catalogues, each with a slightly different type of Book, but the program need not know that.
I think in this case the simple Constructor of codemwnci is best, but there alternative solutions if your situation warrants a more flexible solution.
精彩评论