Array of Objects OutOfBoundsException [duplicate] - java

This question already has answers here:
Are fields initialized before constructor code is run in Java?
(5 answers)
Closed 7 years ago.
i'm (relative) new to java, i have some (minor) understanding of Arrays and Classes/Objects etc. But i can't find the solution to this Errors.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at books$Bookshop.addBook(books.java:42)
at books.main(books.java:57)
My whole Code:
public class books {
static class Book{
private double price;
private String title;
private String isbn;
public Book(double price, String title, String isbn){
this.price = price;
this.title = title;
this.isbn = isbn;
}
public Book makeBook(double price, String title, String isbn){
Book new_book = new Book(price, title, isbn);
return new_book;
}
public String toString(){
String string = this.title + ", " + this.isbn + ", " + this.price;
return string;
}
}
static class Bookshop{
private int stock_max;
Book[] stock = new Book[stock_max];
private int book_counter;
public Bookshop(int size){
this.stock_max = size;
}
public void printBooks(){
for(int i=0; i<stock.length; i++){
System.out.println(stock[i].toString());
}
}
public void addBook(double p, String t, String i){
this.stock[book_counter] = new Book(p,t,i);
}
public void searchBook(String title){
for(int i=0; i<stock.length; i++){
if(title.equals(stock[i].title)){
System.out.println("Book in Stock");
}
}
}
}
public static void main(String[] args) {
Bookshop shop = new Bookshop(10);
shop.addBook(29.90, "title", "24578");
shop.addBook(19.59, "second", "12345");
shop.addBook(69.99, "third title", "47523");
shop.addBook(4.99, "title 4", "98789");
shop.printBooks();
shop.searchBook(args[0]);
}
}
I know that the ArrayIndexOutOfBoundsException means that it tries to make something at an index that doesnt exist. But i set the size of the bookshop to 10, and then add only 4 books to it (Error occurs at the first)...

private int stock_max;
Book[] stock = new Book[stock_max];
private int book_counter;
public Bookshop(int size){
this.stock_max = size;
}
This issue is that stock is set to new Book[stock_max] before the line this.stock_max = size, due to the way Java constructors and initialization is done. stock_max, like all uninitialized ints, starts at 0, so stock is set to an empty array. To fix this, just move the initialization inside the constructor:
private int stock_max;
Book[] stock;
private int book_counter;
public Bookshop(int size){
this.stock_max = size;
this.stock = new Book[stock_max];
}

Related

How to print this objects from start() function

I created 3 classes: Books, autors and main class. I created start() method and objects in it(the task is requiring). Here my cod please can someone explain it or is there better way to do it?
I create array lists, is there better way to do it? I'm very grateful for any help
import java.util.ArrayList;
import java.util.Scanner;
public class BookAuthorStorage<E> {
ArrayList<Book> bookStorage = new ArrayList <>();
ArrayList<Author> authorsStorage = new ArrayList<>();
public void start() {
Book Alchemist = new Book("Alchemist", "That everything is possible", 100, "Paulo Coelho");
Book HarryPotter = new Book("Harry Potter", "The Kind take over evil", 300, "J.K. Rowling");
Book It = new Book("It", "Scary book", 200, "Stephen King");
Author StephenKing = new Author("Stephen", "King", 46, "male", "King#mail.com", "It");
Author Rowling = new Author("Joan", "Rowling", 39, "female", "Rowling.com", "Harry Potter");
Author Coelho = new Author("Paulo", "Coelho", 60, "male", "Coelho.com", "Alchemist");
Scanner scan = new Scanner(System.in);
System.out.println(" Enter 1 to show all books or 2 for authors and 3 for exit");
while (true) {
int choice = scan.nextInt();
switch (choice) {
case 1 -> bookStorage.forEach(System.out::println);
case 2 -> authorsStorage.forEach(System.out::println);
case 3 -> {
System.out.println(" Exiting");
return;
}
default -> System.out.println("Enter again");
}
}
}
public static void main(String[] args) {
BookAuthorStorage bookAuthorStorage1 = new BookAuthorStorage();
bookAuthorStorage1.start();
}
}
When i try to print it prints null, null, null. I overided String in Book and Author classes
public class Author {
public String name;
public String surname;
public int age;
public String gender;
public String email;
Author(String name, String surname, int age, String gender,String email, String book){
}
public String toString(){
return this.name + this.surname + this.age + this.email + this.gender ;
}
}
public class Book {
public String title;
public String description;
public int count = 1000;
public String author;
Book(String title, String description, int count, String author){
}
#Override
public String toString(){
return this.author + this.description + this.title + this.count;
}
}
Create parameterized constructor for Book & Author with all member variables & then initialize both classes in BookAuthorStorage something like:
Author(String name, String surname, int age, String gender,String email, String book){
this.name=name;
this.surname=surname;
this.age=age;
this.gender=gender;
this.email=email;
this.book=book;
}
And inside BookAuthorStorage call :
Book Alchemist = new Book("A","B",1,"C");
..
Author StephenKing = new Author("D","E",1,"F","G");
..
Currently in original code, you are not initializing any String member variable apart from int member variables. So that is reason for your output always have null & int value.
In a constructor, there is no implicit relationships between parameters and internal vars.
You must indicate what you want to do with parameters despite the names are the same :
Book(String title, String description, int count, String author){
this.title = title;
this.description = description;
this.count = count;
this.author = author;
}
It could be better to distinguish both to avoid errors, as parameters' name can be used inside the constructor.
Book(String aTitle, String aDescription, int aCount, String anAuthor){
this.title = aTitle;
this.description = aDescription;
this.count = aCount;
this.author = anAuthor;
}

How can I keep my variables as private and still get the output desired? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
My assignment asks us to make the following variables private as shown: private String title;
private double price; --------these variables can be found on the file Book.java.
My code isn't able to retrieve these variables because they are not visible for the file Textbook.java. How can I keep these variables private, but still get the output desired when I run the TextbookApp.java file. Here is the desired output:
Here is the output I'm getting right now:
Book.java
package assignment2;
public class Book {
private String title;
private double price;
public Book ()
{
title = "";
price = 0.0;
}
public Book (String t, double p)
{
title = t;
price = p;
}
public void setTitle(String t)
{
title = t;
}
public String getTitle()
{
return title;
}
public void setPrice(double p)
{
price = p;
}
public double getPrice()
{
return price;
}
public String toString()
{
return title + " " + price;
}
}
BookApp.java
package assignment2;
public class BookApp {
public static void main(String[] args) {
Book b1 = new Book();
b1.setTitle("John Doe");
b1.setPrice(8.5);
System.out.println(b1.toString());
Book b2 = new Book("Ann Smith", 9.7);
System.out.println(b2.toString());
}
}
Textbook.java
package assignment2;
public class Textbook extends Book{
private int courseID;
public Textbook()
{
title = "";
price = 0.0;
courseID = 0;
}
public Textbook (String t, double p, int ID)
{
title = t;
price = p;
courseID = ID;
}
public void setCourseID(int ID)
{
courseID = ID;
}
public int getCourseID()
{
return courseID;
}
public String toString()
{
return title + " " + price + " " + courseID;
}
}
TextbookApp.java
package assignment2;
public class TextBookApp extends Textbook {
public static void main(String[] args) {
Book b = new Book ("Ann Smith", 9.7);
System.out.println(b.toString());
Textbook tb1 = new Textbook();
tb1.setTitle("John Doe");
tb1.setPrice(8.5);
tb1.setCourseID(2050);
System.out.println(tb1.toString());
Textbook tb2 = new Textbook("Ann Smith", 9.7, 3090);
System.out.println(tb2.toString());
}
}
You can solve the error by calling the appropriate superclass constructor or method in Book from your Textbook subclass:
package assignment2;
public class Textbook extends Book{
private int courseID;
public Textbook()
{
courseID = 0;
}
public Textbook (String t, double p, int ID)
{
super(t, p);
courseID = ID;
}
public void setCourseID(int ID)
{
courseID = ID;
}
public int getCourseID()
{
return courseID;
}
public String toString()
{
return super.toString() + " " + courseID;
}
}
The no-argument constructure Textbook() will automatically call the no-argument constructor Book(), so you don't need to set title and price explicitly in Textbook().

Array is just printing out last element [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I am having this error where it prints out just the last element entered, prints out it the same amount of times as there are elements that are supposed to be in the array.
I have tested it with a System.out.println and the elements that are being added appear to be correct. How do I fix this error?
package stock.control.system;
import java.util.*;
public class StockArrayList implements StockList {
private ArrayList<StockItem> StockItems;
private int index = 0;
private int update;
private int counter = 0;
public StockArrayList() {
StockItems = new ArrayList<StockItem>(counter);
}
#Override
public void addItem(StockItem item) {
StockItem aItem = new StockItem(StockItem.getItemID(),
StockItem.getItemDesc(),
StockItem.getPrice(),
StockItem.getQuantity(),
StockItem.getReOrderLevel());
StockItems.add(counter, aItem);
counter++;
}
#Override
public String formatStockList(){
String temp = StockItem.format();
for (StockItem items : StockItems) {
temp = temp + items.arrayFormat() + "\n";
}
return temp;
}
}
The main method:
public class StockArrayListTester {
public static void main(String[] args) {
StockArrayList Stock = new StockArrayList();
Stock.addItem(new StockItem("P123","1TB Hard drive",75.00,267,50));
Stock.addItem(new StockItem("P125","i7 6800HQ Processor",257.00,113,45));
Stock.addItem(new StockItem("P129","i5 500HQ Processor",127.00,10,45));
Stock.deleteItem("P129");
System.out.printf(Stock.formatStockList());
}
}
the stock item class
package stock.control.system;
import java.util.*;
public class StockItem {
private static String itemID; // Five alpha-numeric characters
private static String itemDesc; // Item description
private static double price; // Item price in pounds sterling
private static int quantity; // Quantity in stock
private static int reOrderLevel; // Level at which to re-order
public StockItem(String itemID, String itemDesc, double price, int quantity, int reOrderLevel) {
this.itemID = itemID;
this.itemDesc = itemDesc;
this.price = price;
this.quantity = quantity;
this.reOrderLevel = reOrderLevel;
}
#Override
public String toString() {
String toString ="[Item ID = " + this.itemID + ", Item Description = " +
this.itemDesc + ", Price = " + this.price + ", Quantity = " +
this.quantity + ", Re Order Level = " + this.reOrderLevel + "]";
return toString;
}
public static String format() {
String format = " STOCK ITEMS"
+ String.format("\n%-10s%-30s%-10s%-12s%-14s%-10s%-30s%-10s%-12s%-14s\n",
"ItemID","Item Description",
"Price","Quantity", "Re Order Level", "\n******",
" ****************"," *****", " ********",
" **************");
return format;
}
public String arrayFormat() {
return String.format("%-10s%-30s%-10s%-12s%-14s",
StockItem.getItemID(),
StockItem.getItemDesc(),
StockItem.getPrice(),
StockItem.getQuantity(),
StockItem.getReOrderLevel());
}
public static String getItemID(){
return itemID;
}
public static String getItemDesc() {
return itemDesc;
}
public static double getPrice() {
return price;
}
public double setPrice(double price) {
this.price = price;
return price;
}
public static int getQuantity() {
return quantity;
}
public int setQuantity(int quantity) {
this.quantity = quantity;
return quantity;
}
public static int getReOrderLevel(){
return reOrderLevel;
}
public int setReOrderLevel(int reOrderLevel){
this.reOrderLevel = reOrderLevel;
return reOrderLevel;
}
}
The output I get is:
STOCK ITEMS
ItemID Item Description Price Quantity Re Order
P129 i5 500HQ Processor 127.0 10 45
P129 i5 500HQ Processor 127.0 10 45
P129 i5 500HQ Processor 127.0 10 45
BUILD SUCCESSFUL (total time: 0 seconds)
As a rule, never set static fields in a constructor. It is almost certainly a bug. IMHO, this should be a compiler error but it's not.
In this case, you are expecting each instance of StockItem to be different, however by making the fields static you are ensuring there is only one copy, only one value for those fields. I suggest you make them instance fields.
public class StockItem {
private final String itemID; // Five alpha-numeric characters
private final String itemDesc; // Item description
private double price; // Item price in pounds sterling
private int quantity; // Quantity in stock
private int reOrderLevel; // Level at which to re-order
public StockItem(String itemID, String itemDesc, double price, int quantity, int reOrderLevel) {
this.itemID = itemID;
this.itemDesc = itemDesc;
this.price = price;
this.quantity = quantity;
this.reOrderLevel = reOrderLevel;
}
It's been a little while since I've used Java but it seems weird that in your addItem() method in your StockList class that you pass in a parameter 'item' but then never use it inside the method.
Why are you trying to "get" all of the properties of the stock item to add when you are passing them in to the function as a StockItem object?
Guess something is wrong here:
#Override
public void addItem(StockItem item) {
StockItem aItem = new StockItem(StockItem.getItemID(),
StockItem.getItemDesc(), StockItem.getPrice(), StockItem.getQuantity(), StockItem.getReOrderLevel());
StockItems.add(counter, aItem);
counter++;
}
All those getters are static methods. It does not make sense to me since I would think you want to get instance variables belonging to different objects. You must have initialiazed the StockItem class instance variables with the values printed out, otherwise I do not think your code would even compile.
Anyway why not adding the item passed as a parameter directly to the stock list?
Like so:
#Override
public void addItem(StockItem item) {
StockItems.add(counter, item);
counter++;
}

Scanner error in Code, building array using reference variables

I'm still pretty new to coding, so my apologies if this has an obvious fix.
I'm trying to build a library that can store book objects, but before I can work on functionality, I need to get an array sorted out. Java itself does not show any errors in my side bar, but when ran through the console, an error appears.
Below I have posted my Library.java class.
import java.util.Scanner;
public class Library {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
Book[] books = new Book[2];
String Title;
String Author;
String BookID;
Boolean onLoan;
int NumberofLoans;
for( int i = 0; i < books.length; i++){
System.out.print("Enter the title of the book: ");
Title = input.next();
books[i] = new Book();
books[i].setTitle(Title);
System.out.println("");
System.out.print("Enter the Author of the book: ");
Author = input.next();
books[i].setAuthor(Author);
System.out.println("");
System.out.print("Enter the Book's ID: ");
BookID = input.next();
books[i].setBookID(BookID);
System.out.println("");
NumberofLoans = 0;
books[i].setNumberofLoans(NumberofLoans);
onLoan = false;
books[i].setonLoan(onLoan);
input.close();
}
for(int i = 0; i < books.length; i++){
System.out.println("Title: " + books[i].getTitle());
System.out.println("Author: " + books[i].getAuthor());
System.out.println("BookID: " + books[i].getBookID());
System.out.println("Times loaned: " + books[i].getNumberofLoans());
System.out.println("In library: " + books[i].getonLoan());
}
}
}
The console error itself, is listed below:
Exception in thread "main" Enter the title of the book:
java.lang.IllegalStateException: Scanner closed
at java.util.Scanner.ensureOpen(Scanner.java:1070)
at java.util.Scanner.next(Scanner.java:1358)
at Library.main(Library.java:19)
Could someone pin-point where in my code the error is coming from? Then, changes I could make to stop this error from occurring?
Just to make sure that everything is listed, I will post Book.java, in case the error originates from in there.
public class Book {
private String Title;
private String Author;
private String BookID;
private Boolean onLoan;
private int NumberofLoans;
public Book(){
Title = new String();
Author = new String();
BookID = new String();
onLoan = false;
NumberofLoans = 0;
}
public void setTitle(String title) {
this.Title = title;
}
public void setAuthor(String author) {
this.Author = author;
}
public void setBookID(String bookID) {
this.BookID = bookID;
}
public void setonLoan(Boolean onLoan) {
this.onLoan = onLoan;
}
public void setNumberofLoans(int numberofLoans) {
this.NumberofLoans = numberofLoans;
}
public String getTitle() {
return Title;
}
public String getAuthor() {
return Author;
}
public String getBookID() {
return BookID;
}
public Boolean getonLoan() {
return onLoan;
}
public int getNumberofLoans() {
return NumberofLoans;
}}
In Library class' first loop is causing this. Specifically, this line:
input.close();
Because you are closing the Scanner before it has been used completely by whole program. Scanner is available first time the loop runs. But after first execution, you close the scanner. Hence for the consecutive loop runs, scanner is closed and hence the error.
Add this line after loop finishes. In other words, something like this:
for( int i = 0; i < books.length; i++){
// ... Whatever
}
input.close();

JAVA Null pointer Exception getTitle method, I can't find it

There's no error while coding it, but when i ran it, it said
Exception in thread "main" java.lang.NullPointerException
at homework.Book.getTitle(Book.java:36)
at homework.BookMain.main(BookMain.java:61)
Java Result: 1
***********************************
package homework;
public class BookMain {
public static void main(String[] args){
int i;
int option;
Book[] bookSet = new Book[20];
bookSet[0] = new Book("I dare you","Joyce Meyer",2007);
bookSet[1] = new Book("Straight from the Heart","Rev. Fr. Mario Jose C. Ladra",2012);
bookSet[2] = new Book("Deliverance From Fear","Bob Buess",1993);
bookSet[3] = new Book("Extraordinary Book of Facts","Bathroom Readers' Institute",2006);
bookSet[4] = new Book("Fat Kid Rules the World","K.L. Going",2003);
Book.numberOfBooks = 5;
Book getter = new Book();
for (i=0; i<Book.numberOfBooks; i++)
{
System.out.println(getter.getTitle(bookSet[i])+" "+getter.getAuthor(bookSet[i])+" "+getter.getYear(bookSet[i]));
}
System.out.println();
for (i=0; i<Book.numberOfBooks; i++)
{
if(getter.getYear(bookSet[i])>2000)
System.out.println(getter.getTitle(bookSet[i])+" "+getter.getAuthor(bookSet[i])+" "+getter.getYear(bookSet[i]));
}
bookSet[5] = new Book("The Lake of Dead Languages","Carol Goodman",2002);
Shelf shelf1 = new Shelf("Shelf1","Bedroom");
Shelf shelf2 = new Shelf("Shelf2","Living room");
Shelf shelf3 = new Shelf("Shelf3","Basement");
Shelf placer = new Shelf();
placer.insertBook(shelf1,bookSet[1]);
placer.insertBook(shelf1,bookSet[2]);
placer.insertBook(shelf2,bookSet[3]);
placer.insertBook(shelf2,bookSet[4]);
placer.insertBook(shelf1,bookSet[5]);
placer.insertBook(shelf1,bookSet[0]);
System.out.println(placer.getShelfName(shelf1)+" "+placer.getLocation(shelf1));
Book aBookInShelf = new Book();
for(i=0; i<shelf1.booksInShelf; i++)
{
aBookInShelf = placer.pickBook(shelf1, i);
System.out.println(getter.getTitle(aBookInShelf)+" "+getter.getAuthor(aBookInShelf)
+" "+getter.getYear(aBookInShelf));
}
}
}
===========================================
Books class:
package homework;
public class Book {
private String title;
private String author;
private int year;
public static int numberOfBooks = 0;
public Book(String title, String author, int year){
this.title=title;
this.author=author;
this.year=year;
}
public Book(){
}
public String getAuthor(Book target){
return target.author;
}
public int getYear(Book target){
return target.year;
}
public String getTitle(Book target){
return target.title;
}
public static void main(String[] args){
}
}
=====================================
Shelves class:
package homework;
public class Shelf {
private String name;
private String location;
public static int booksInShelf=0;
private Book[] shelfBooks = new Book[20];
public Shelf(String name, String location){
this.name = name;
this.location = location;
}
public Shelf(){
}
public String getShelfName(Shelf target){
return target.name;
}
public String getLocation(Shelf target){
return target.location;
}
public void insertBook(Shelf target, Book aBook){
target.shelfBooks[target.booksInShelf] = aBook;
target.booksInShelf++;
}
public Book pickBook(Shelf target, int nthBook){
return target.shelfBooks[nthBook];
}
}
Beside getter/setter design madness it seems that NullPointerException is caused by fact that booksInShelf is static, which means that it belongs to entire Shelf class (instances of this class share value of this field) so when you add book to one Shelf and increment this field, it will be incremented for all instances of Shelf.
Because of that in loop
for(i=0; i<shelf1.booksInShelf; i++)
you are iterating even over positions that were not set yet and are still nulls. Now in
aBookInShelf = placer.pickBook(shelf1, i);
System.out.println(getter.getTitle(aBookInShelf)+" "+getter.getAuthor(aBookInShelf)
+" "+getter.getYear(aBookInShelf));
you are picking this null and using it inside getter.getTitle(null) which will try to invoke return null.title which will case NPE because null doesn't have title.
To fix this problem remove static modifier from booksInShelf field.

Categories