容器 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++;
}
我有一个问题,我不知道如何解决。
所以我有 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++;
}