Java method parameter for creating new object of different class - java

I have searched high and low for a solution to this problem, and finally signed up here to see if someone can point me to what is undoubtedly a really simple solution that is evading me. I'm working on MIT's OpenCourse to teach myself Java and am stumped on this problem.
I have two classes, Library and Book. The program keeps track of books created for each library, their location, and whether or not they are checked out. I am given the main method for Library that cannot be edited. Instead its methods must be built to produce the desired output. The issue I am having is determining the argument syntax to pass to a method in Library that creates a new Book in the main method of Library.
Relevant Library Code:
package mitPractice;
public class Library {
String library_address;
static String library_hours = "Libraries are open daily from 9AM to 5PM";
Book[] catalog;
//List of Methods for Libraries
public Library(String address) {
library_address = address;
}
public static void printOpeningHours() {
System.out.println(library_hours);
}
public void addBook(/*unsure what parameter to add here*/) {
catalog[ (catalog.length + 1)] = //unknown parameter
}
public static void main(String[] args) {
//Create two libraries
Library firstLibrary = new Library("10 Main St.");
Library secondLibrary = new Library("228 Liberty St.");
//Add four books ***This block of code is the problem and is uneditable
firstLibrary.addBook(new Book("A Game of Thrones"));
firstLibrary.addBook(new Book("Rama"));
firstLibrary.addBook(new Book("Understanding Space"));
firstLibrary.addBook(new Book("Way of the Clans"));
So my question is how to make the method compatible with the code given in the main method? I have attempted numerous combinations for arguments to pass to addBook() and none seem to deliver.
Book code:
package mitPractice;
public class Book {
Boolean isCheckedOut = false;
String book_title;
public Book(String title) {
book_title = title;
}
public void Borrow() {
isCheckedOut = true;
}
public void Return() {
isCheckedOut = false;
}
public boolean isBorrowed() {
if (isCheckedOut == true) {
return true;
} else {
return false;
}
}
public String getTitle() {
return book_title;
}
/*public static void main(String[] args) {
Book example = new Book("A Game of Thrones");
System.out.println("Title: " + example.getTitle());
System.out.println("Borrowed?: " + example.isBorrowed());
example.Borrow();
System.out.println("Borrowed?: " + example.isBorrowed());
example.Return();
System.out.println("Borrowed?: " + example.isBorrowed());
}*/
}

You want the parameter to be of type Book:
public void addBook(Book newBook) {
catalog[(catalog.length + 1)] = newBook;
}
This will throw an ArrayIndexOutOfBoundsException though, because you're trying to put an element in the array after the last index. You'll need to keep track of how many books have been added and rebuild your array when it gets full. Like this:
private int numberOfBooks = 0;
public void addBook(Book newBook) {
numberOfBooks++;
if(numberOfBooks >= catalog.length) {
// Rebuild array
Book[] copy = new Book[catalog.length * 2]
for(int i=0; i<catalog.length; i++){
copy[i] = catalog[i];
}
catalog = copy;
}
catalog[numberOfBooks] = newBook;
}
Or use a collection like java.util.ArrayList.
So instead of having this line:
Book[] catalog;
You might have
ArrayList<Book> catalog = new ArrayList<Book>();
This creates an ArrayList which is a Java implementation of a dynamically sized array.
Then your addBook method might look like this:
public void addBook(Book newBook) {
catalog.add(newBook);
}
In order to use ArrayList you'll need to include this line at the beginning of the file, after the package mitPractice; line:
import java.util.ArrayList;

This always ends in array out of bounds :
public void addBook(/*unsure what parameter to add here*/) {
catalog[ (catalog.length + 1)] = //unknown parameter
}
Actually, the best would be to use List :
public class Library {
List<Book> catalog = new ArrayList<>();
...
}
Then you can simply do this :
public void addBook(Book book) {
catalog.add(book);
}

Try this code. This will add a book to a very important data structure called an ArrayList found in the util package in java. A programmer has to import this before the class statement but after any package statement. The code also uses a method from your Book API to print the title when a book is successfully added to the ArrayList. ArrayLists are favourable over Arrays because an java.util.ArrayList can expand without problems whereas an Array is a fixed size and is not so dynamic.
Check out this code I modified of the Library class that compiles and runs.
package mitPractice;
import java.util.ArrayList;
public class Library {
String library_address;
static String library_hours = "Libraries are open daily from 9AM to 5PM";
ArrayList<Book> books = new ArrayList<Book>();
//List of Methods for Libraries
public Library(String address) {
library_address = address;
}
public static void printOpeningHours() {
System.out.println(library_hours);
}
public void addBook(Book b/*unsure what parameter to add here*/) {
books.add(b); // add the book to the ArrayList
System.out.println("The book: " + b.getTitle() + " was successfully added.");
}
public static void main(String[] args) {
//Create two libraries
Library firstLibrary = new Library("10 Main St.");
Library secondLibrary = new Library("228 Liberty St.");
//Add four books ***This block of code is the problem and is uneditable
firstLibrary.addBook(new Book("A Game of Drones"));
firstLibrary.addBook(new Book("Raman Noodles"));
firstLibrary.addBook(new Book("Understanding Space"));
firstLibrary.addBook(new Book("Way of the Yoga Baywatch Babes"));
} // end main
} // end Library class
I hope this helps some.
All the best,
user_loser

Related

What is the difference between the two marked methods? Are their outputs the same?

This code was questioned in an exercise I had to solve. Although my code shows the right result (version one), I'm not sure if it is as good as the solution provided (version two) or if it is correct at all. The task is to write a class which is representing a book and methods to page forward and backward using self-references.
public class Book {
private int page;
private Book nextPage;
public Book(int page) {
setPage(page);
setNextPage(null);
}
//Getter and Setter
public void setPage(int page){
this.page = page;
}
public int getPage() {
return this.page;
}
public void setNextPage(Book nextPage) {
this.nextPage = nextPage;
}
public Book getNextPage() {
return nextPage;
}
/*The following methods are getting two int values and should page backward, showing each page number. */
Version one:
public static void pageBackward1(int currentPage, int goalPage) {
Book page = new Book(currentPage);
System.out.print("Page " + page.getPage() + " ");
while(goalPage != page.getPage()) {
currentPage--;
page.nextPage = new Book(currentPage);
page = page.nextPage;
System.out.print("Page " + page.getPage() + " ");
}
}
Version two:
public static void pageBackward2(int currentPage, int goalPage) {
Book previousPage = null;
for(int i = currentPage; i <= goalPage; i++) {
Book page = new Book(i);
page.setNextPage(previousPage);
previousPage = page;
}
Book page = previousPage;
while(page != null) {
System.out.print("Page " + page.getPage() + " ");
page = page.getNextPage();
}
System.out.println();
}
}
The following demo-class is simple and shows the execution of the methods:
public class BookDemo {
public static void main(String[] args) {
Book.pageBackward1(500, 455);
System.out.println();
Book.pageBackward2(500, 455);
}
}
The solutions, as you've said, are equivalent (literally! Upon the same input data they output the same data, despite through stdout instead of a return value).
I believe due to the supplied solution that the exercise's proposal was to pre-fill/pre-generate the Books before stepping through them using the getNextPage() getter. I believe you've reached the same conclusion since you did almost the same thing but in a different order, stepping through the instances once but as you create them (as opposed to, for example, stepping through all of the existing Books to arrive at the final one before creating the next).
In my opinion this exercise simply fails to teach much due to these wonky semantics and unclear goals, and it would be much more productive for students to start working straight out with more explicitly named and generic linked list data structures.

Call data from a string array to another class

public class QuestionBank {
public static void main(String[] args) {
int k = 0;
String Bank[][] = {{"The sun is hot.","A. True","B. Flase","A"},
{"Cats can fly.","A. True","B. False","B"}};
}
}
Above is my QuestionBank class that creates a 2X4 string array. First column being the question, 2nd and 3rd being the answer choices, and 4th being the correct answer.
Below is my RealDeal class.
import javax.swing.JOptionPane;
import java.util.Scanner;
public class RealDeal {
public static void main(String[] args) {
input = JOptionPane.showInputDialog(Bank[0][0]\nBank[0][1]\nBank[0][2]);
if (input == Bank[0][3]) {
input = 10;
} else {
input = 0;
}
total = input/1;
JOptionPane.showMessageDialog(null,"You scored a " + total + " out of 10. Great job!");
System.exit(0);
}
}
What I'm trying to do is to get Bank[0][0], Bank[0][1], and Bank[0][2] to output on my RealDeal class and then to check whether Bank[0][3] matches with the users input. Can anyone please help me with this. Im really new to java so if anyone could actually draw out the answer and explain it to me that would be great.
I think the best way is reading a good Java book and become familiar with the language itself and then try to solve this by your own. If you then have a real question there is no problem asking it here again. But your code is... not really working at all.
I don't think this portal is a "please do my work for me" portal.
To call anything from another class you will need to either setup a method for a return or make the variables public.
So:
public class Class1
{
// for method 1
public String s1 = "This is a string"
// for method 2
public Class1 {}
public returnString()
{
return s1;
}
}
public class CLASS2
{
public static void main(String args[])
{
// get the class
cls1 = new Class1();
// retrieving - method 1
String str = cls1.s1;
// retrieving - method2
str = cls1.returnString();
}
}

building a test program in java

Hello I am new to Java and NetBeans and am in Advanced classes in which my classes are 5 weeks long, so it is a lot to learn a new code language in 5 weeks. Anyways I have an assignment to Create a class named Movie that holds a movie name and rating. Provide methods to get and set both the movie name and rating. Create a class named TestMovie that creates three Movie instances with different values for name and rating and prints the information about each movie. I have done the code and it is passing the build fine but my professor wants a screen shot of the program working and running but I can't get NetBeans to bring that up. The chapter on building the test project was ripped out of my book. Can I get some help or pointers here is the code I have done:
package movie;
/**
*
* #author Jason
*/
public class Movie {
String movieRating;
public Movie(String rated, String mtitle) {
this.mrating = rated;
this.title = mtitle;
}
public void setRating(String Rating) {
movieRating = Rating;
}
// Get the rating
public String getRating() {
return movieRating;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
#Override
public String toString() {
return "Movie" + " title=" + getTitle() + " rating=" + getRating();
}
public static void main(String args[]) {
Movie mv = new Movie("", "");
mv.toString();
}
private String title;
private String mrating;
}
You can just run a test on the console, that is, create a MovieTest class with only a main method and create three instances/objects of Movie (Movie m1, m2, m3; OR Movie[] movies;). Assign them values either in the constructor or with the set methods then print them out with the method print or println in System.out.
Something along the lines of:
public class MovieTest {
public static void main(String[] args) {
Movie[] movies = new Movie[] {new Movie("R1", "T1"), new Movie("R2", "T2"), new Movie("R3", "T3)";
for (Movie i : movies) {
System.out.println(i.toString());
}
}
}
Then end by screenshooting the results.
As an alternative to the other answers suggesting printing the output to the console, with the Netbeans' UI editor you can easily create a window with a label showing the result, which makes it slightly more fancy.
You can get details on how to this here. Here's an image from that page:
The full working code is here. As you can see, it's just a few extra lines.
Your application prints no output, because you invoke toString(), but you don't print the result of it.
An example to create 3 Movie instances with data,
print them out, and then make a screenshot of your console app.
public static void main(String args[]) {
List<Movie> movieList = new ArrayList<Movie>(3);
Movie mv1 = new Movie("very Good", "Testfilm 1");
movieList add(mv1);
mv1 = new Movie("good", "Testfilm 2");
movieList add(mv1);
mv1 = new Movie("not good", "Testfilm 2");
movieList add(mv1);
for (Movie m : movieList) {
System.out.println(m.toString());
}
}

Java-How do I call a class with a string?

I am a beginner programmer and this is my first question on this forum.
I am writing a simple text adventure game using BlueJ as a compiler, and I am on a Mac. The problem I ran into is that I would like to make my code more self automated, but I cannot call a class with a string. The reason I want call the class and not have it all in an if function is so that I may incorporate more methods.
Here is how it will run currently:
public class textadventure {
public method(String room){
if(room==street){street.enterRoom();}
}
}
public class street{
public enterRoom(){
//do stuff and call other methods
}
}
The if statement tests for every class/room I create. What I would like the code to do is automatically make the string room into a class name that can be called. So it may act like so:
Public method(string room){
Class Room = room;
Room.enterRoom();
}
I have already looked into using Class.forName, but all the examples were too general for me to understand how to use the function. Any help would be greatly appreciated, and if there is any other necessary information (such as more example code) I am happy to provide it.
-Sebastien
Here is the full code:
import java.awt.*;
import javax.swing.*;
public class Player extends JApplet{
public String textOnScreen;
public void start(){
room("street1");
}
public void room(String room){
if(room=="street1"){
textOnScreen=street1.enterRoom();
repaint();
}
if(room=="street2"){
textOnScreen=street2.enterRoom();
repaint();
}
}
public void paint(Graphics g){
g.drawString(textOnScreen,5,15);
}
}
public abstract class street1
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on a street running from North to South.";
return textToScreen;
}
}
public abstract class street2
{
private static String textToScreen;
public static String enterRoom(){
textToScreen = "You are on another street.";
return textToScreen;
}
}
Seeing as you are rather new to programming, I would recommend starting with some programs that are simpler than a full-fledged adventure game. You still haven't fully grasped some of the fundamentals of the Java syntax. Take, for example, the HelloWorld program:
public class HelloWorld {
public static void main(String[] args) {
String output = "Hello World!"
System.out.println(output);
}
}
Notice that public is lowercased. Public with a capital P is not the same as public.
Also notice that the String class has a capital S.* Again, capitalization matters, so string is not the same as String.
In addition, note that I didn't have to use String string = new String("string"). You can use String string = "string". This syntax runs faster and is easier to read.
When testing for string equality, you need to use String.equals instead of ==. This is because a == b checks for object equality (i.e. a and b occupy the same spot in memory) and stringOne.equals(stringTwo) checks to see if stringOne has the same characters in the same order as stringTwo regardless of where they are in memory.
Now, as for your question, I would recommend using either an Enum or a Map to keep track of which object to use.
For example:
public class Tester {
public enum Location {
ROOM_A("Room A", "You are going into Room A"),
ROOM_B("Room B", "You are going into Room B"),
OUTSIDE("Outside", "You are going outside");
private final String name;
private final String actionText;
private Location(String name, String actionText) {
this.name = name;
this.actionText = actionText;
}
public String getActionText() {
return this.actionText;
}
public String getName() {
return this.name;
}
public static Location findByName(String name) {
name = name.toUpperCase().replaceAll("\\s+", "_");
try {
return Enum.valueOf(Location.class, name);
} catch (IllegalArgumentException e) {
return null;
}
}
}
private Location currentLocation;
public void changeLocation(String locationName) {
Location location = Location.findByName(locationName);
if (location == null) {
System.out.println("Unknown room: " + locationName);
} else if (currentLocation != null && currentLocation.equals(location)) {
System.out.println("Already in room " + location.getName());
} else {
System.out.println(location.getActionText());
currentLocation = location;
}
}
public static void main(String[] args) {
Tester tester = new Tester();
tester.changeLocation("room a");
tester.changeLocation("room b");
tester.changeLocation("room c");
tester.changeLocation("room b");
tester.changeLocation("outside");
}
}
*This is the standard way of formating Java code. Class names are PascalCased while variable names are camelCased.
String className=getClassName();//Get class name from user here
String fnName=getMethodName();//Get function name from user here
Class params[] = {};
Object paramsObj[] = {};
Class thisClass = Class.forName(className);// get the Class
Object inst = thisClass.newInstance();// get an instance
// get the method
Method fn = thisClass.getDeclaredMethod(fnName, params);
// call the method
fn.invoke(inst, paramsObj);
The comments below your question are true - your code is very rough.
Anyway, if you have a method like
public void doSomething(String str) {
if (str.equals("whatever")) {
// do something
}
}
Then call it like
doSomething("whatever");
In Java, many classes have attributes, and you can and will often have multiple instances from the same class.
How would you identify which is which by name?
For example
class Room {
List<Monster> monsters = new ArrayList <Monster> ();
public Room (int monstercount) {
for (int i = 0; i < monstercount; ++i)
monsters.add (new Monster ());
}
// ...
}
Monsters can have attributes, and if one of them is dead, you can identify it more easily if you don't handle everything in Strings.

Java Object Array Foreach Method Access

After developing in PHP for a long time I have decided to step into Java. Comfortable in OOP methodology and all that, I'm trying to start off at that point within java, but I'm getting hung up on passing out my arraylist object into a for statement to be printed back out using the Item class methods.
HelloInvetory.java
package helloInventory;
import java.util.Arrays;
public class HelloInventory {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Object InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
}
Inventory.java
package helloInventory;
import java.util.*;
/**
* Tracks and maintains all items within the inventory
* #author levi
*
*/
public class Inventory {
List<Object> InventoryItems = new ArrayList<Object>();
/*
* create object from Items class
* and insert into Object[] array.
*/
public void createItemObj(int sku, String name, String descriptor, float price) {
Items item = new Items();
item.setSku(sku);
item.setItemName(name);
item.setItemDescription(descriptor);
item.setItemPrice(price);
this.setInventoryItems(item);
}
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
public void setInventoryItems(Object inventoryItems) {
//InventoryItems.add(inventoryItems);
this.InventoryItems.add(inventoryItems);
}
}
Items.java
package helloInventory;
/**
* Class object to hold each item details
* #author levi
*
*/
public class Items {
int sku;
String itemName;
String itemDescription;
float itemPrice;
public int getSku() {
return sku;
}
public void setSku(int sku) {
this.sku = sku;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemDescription() {
return itemDescription;
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDescription;
}
public float getItemPrice() {
return itemPrice;
}
public void setItemPrice(float itemPrice) {
this.itemPrice = itemPrice;
}
}
Where I am stuck is within the HelloInventory.java
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
IDE (Eclipse) gives me the error "Can only iterate over an array or an instance of java.lang.Iterable". Is there something extra I need, or I'm I going around this totally the wrong way in Java? Correct example would be helpful.
Best,
Levi
You have a very strange architecture here my friend. You shouldn't be using generic Objects everywhere, but the actual types. First thing:
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
Why not just return the List itself?
public List<Item> getAllInventoryItems() {
return this.InventoryItems;
}
Also change this:
List<Item> InventoryItems = new ArrayList<Item>();
and this:
public void setInventoryItems(Item inventoryItems) {
this.InventoryItems.add(inventoryItems);
}
Now iterating the List is smooth sailing:
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Item> InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Item item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
Btw, I changed Items to Item out of habit. A class name should indicate a single entity so by convention it's singular.
Now don't take this the wrong way, but you may have got off on the wrong foot with Java, so I highly recommend this reading: http://www.mindview.net/Books/TIJ/ This worked for me when I was starting with Java, maybe others can suggest some good sources as well.
Ok, two things. One is that Tudor is absolutely right, it's best to use the classes you're expecting directly, not Objects, and stylistically his points are accurate too.
Two is that if you really have to use a list of object, you'll need to cast back from object to whatever type it is that you're expecting to receive.
List<Object> list = inv.getAllInventoryItems();
for (Object item : list){
System.out.println((Items) item).getItemName();
}
However, I wouldn't recommend doing this as it effectively takes what should be a compile-time error and makes it a RunTime error (if the class cannot be cast).

Categories