Java Pass object to method - java

I have a program that allows the user to choose between a binary search tree a splay tree and a red black tree. I wrote the class for the binary search tree and now im working on the splay tree but ive realized that my method that interacts with the user only works with the binary search tree. I set it up so that it will create an instance of whichever tree the user selects but down in my code I use only the variable that would be created if the user selected a binary search tree. My question is how can i make it so that I will only create an instance of the tree that the user selected and how can i use only one variable so that when i insert items or work on the tree i dont have to add more conditional statements for different trees?
this is what i have now
import java.util.Scanner;
import java.lang.Math.*;
public class Driver1
{
public static void main(String[] args)
{
//local variables
String treeChoice = null;
String choice = null;
String choice2 = null;
String command = null;
int insertAmount = -1;
String pattern;
int height = -1;
int i = -1;
//BST<Integer> myTree = null;
//ST<Integer> mySTTree = null;
int num = 0;
//Scanners to take user input
Scanner input = new Scanner(System.in);
Scanner inputt = new Scanner(System.in);
System.out.println("Which tree would you like to test (BST, ST, RBT)? ");
treeChoice = input.nextLine();
//Based on user input either a BST, Splay Tree, or RBT will be initialized.
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
else if("ST".equalsIgnoreCase(treeChoice))
{
//System.out.println("Splay Tree not ready yet");
ST<Integer> mySTTree = new ST<Integer>();
}
else if("RBT".equalsIgnoreCase(treeChoice))
{
System.out.println("RBT not ready yet");
//RBT<Integer> myTree = new RBT<Integer>();
}
else
{
System.out.println("Invalid Entry");
}
//Ask user how many items to input
System.out.println("How many items would you like to insert? ");
insertAmount = input.nextInt();
//ask user if the items will be random or sorted
System.out.println("Pattern (random or sorted): ");
choice2 = inputt.nextLine();
//If random, create random numbers
if("random".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert((int)(Math.random()*1000000)+i);
}
}
//else fill the tree with numbers in order from 1 to the user limit
else if("sorted".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert(i);
}
}
//Keep asking users input on what to do to the tree until user says quit
while(command != "quit")
{
System.out.println(
"Next command (insert X, delete X, find X, height, quit)?");
command = inputt.nextLine();
if (command.startsWith("insert"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.insert(num);
if(result == false)
{
System.out.println("Item already present.");
}
}
else if(command.startsWith("delete"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.delete(num);
}
else if(command.startsWith("find"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.find(num);
if(result == true)
{
System.out.println("Item present.");
}
else
{
System.out.println("Item not present.");
}
}
else if(command.startsWith("height"))
{
System.out.println("Current height of tree " + myTree.height());
}
else if(command.startsWith("quit"))
{
break;
}
System.out.println();
}
}//Close main method
as you can see I fill only myTree which would be the tree created if the user selected bst. and in the while loop i only work on myTree.
How can i make this more generic or my other idea was to take the users input and then create the instance of that tree and then pass the instance into a seperate method so that i could still use only myTree since it would refer to the instance that was passed into that method but im not sure how to pass an instance into another method. This way seems like the best but im not sure
any help is appreciated

Your trees should extend a common base class, or better, a implement common interface, say Tree, that specifies the methods to be used on all trees (find, insert, delete). Then you should have only one variable Tree myTree to which you assign an actual instance of the type the user selects.
Are you sure your above code works, however? If you do this
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
then the variable myTree will be unavailable after the } because the code block in which it is declared ends there. You can declare a variable at one point and assign a value to it later, like so:
Tree<Integer> myTree;
if("BST".equalsIgnoreCase(treeChoice)) {
myTree = new BinarySearchTree<Integer>();
} else if("ST".equalsIgnoreCase(treeChoice)) {
myTree = new SplayTree<Integer>();
} else if("RBT".equalsIgnoreCase(treeChoice)) {
myTree = new RedBlackTree<Integer>();
} else {
throw new IllegalArgumentException(treeChoice + " is not a valid input");
}
I very much recommend that you give your classes real names that make obvious what they represent, not just two or three letter combinations. Note that if you do not throw an exception in the last else branch, the compiler will later complain that "the variable myTree may not have been initialized".
Alternatively, you could put all your code after the tree creation if-else-statements into a method, say <T> void testTree(Tree<T> myTree) and call this method directly where you evaluate the user input, e.g. if("BST".equalsIgnoreCase(treeChoice)) testTree(new BinarySearchTree<Integer>());, but at some you will want to assign it to a variable anyway.

Related

How do I search for null in this ArrayList and then replace it with another Object?

I have been writing code of a car parking structure for a bit now and i've gotten kinda stuck. So far I have an ArrayList that the user adds Vehicle properties to aswell as an ArrayList for a parking space with a "SpaceID" and the "Vehicle" from earlier.
So far I can make it so that the user adds the vehicle, and the vehicle gets added to a parking space, However I have made a temporary parking space with the index 0: and the element (vehicle) being null.
From here, I wanted to check the parking space ArrayList for "null" and then if it's found, replace null with the vehicle, However, I do not know how to go about implementing this. I will attach the current code i'm using, or at least a minimal version of it.
I have already tried using a Contains(null) method, but I can't seem to get that to work properly, I'm not sure if it even can work, but I have since then removed it from my code.
First of all, I have the function to create the vehicle and store it in an Array.
```
public void carInfo(Vehicle tempVehicle, parkingSpace vehicle) {
array = new MCP();
System.out.println("Please enter number plate: ");
input = new Scanner(System.in);
String plate = input.nextLine();
System.out.println("Please enter car make: ");
input = new Scanner(System.in);
String make = input.nextLine();
System.out.println("How would you best describe your Vehicle? ");
System.out.println("(Car, Small Van, Tall Van, Long Van, Coach,
Motorbike)");
type = new Scanner(System.in);
String type1 = input.nextLine();
if (type1.equalsIgnoreCase(vehicleType.CAR.toString())) {
tempVehicle.setPlate(plate);
tempVehicle.setCarMake(make);
tempVehicle.setVehicle(vehicleType.CAR);
inv.createInvoice();
tempVehicle.setInvoiceNumber(inv.invoiceNumber);
array.addStandard(tempVehicle);
array.parkVehicle(vehicle);
System.out.println(tempVehicle.toString());
System.out.println(vehicle.toString());
```
I also have my Arrays, which are on another class.
```
public MCP(){
vehicles = new ArrayList<>();
parkingSpaces = new ArrayList<>();
parkingSpaces.add(0, null);
parkingSpaces.add(1, null);
}
public void addStandard(Vehicle tempVehicle) {
vehicles.add(tempVehicle);
}
public void parkVehicle(parkingSpace vehicle) {
parkingSpaces.add(vehicle);
}
```
This is the way I tried to do it, but I couldn't figure this way out, so I stopped, i'm open to any other ways too.
// public void checkIfEmpty(parkingSpace vehicle){
// if(parkingSpaces.contains(null)){
// parkingSpaces.add(vehicle);
// }
// else{
// System.out.println("There is no room in this Zone");
// }
// }
I am also looking for a better way to populate parking spaces, but that's not the main concern, just something else just incase someone has any ideas
Thanks in Advance.
Since you are using an array list, when an item is deleted from it, there will be no empty element between two elements in it. When you delete an element, the elements shift. So in the case of this code, it checks if the number of elements in the array list is smaller than maximum number of cars
int maxSize = 10; //suppose that the maximum number of cars is 10
public void checkIfEmpty(parkingSpace vehicle){
if(parkingSpaces.size() < maxSize){
parkingSpaces.add(vehicle);
}
else{
System.out.println("There is no room in this Zone");
}
}
Try doing something like this:
public void checkIfEmpty(parkingSpace vehicle) {
boolean addedVehicle = false;
for (int i = 0; i < parkingSpaces.size(); i++){
if (parkingSpaces.get(i) == null) {
parkingSpaces.add(vehicle);
addedVehicle = true;
break;
}
}
if (!addedVehicle)
System.out.println("There is no room in this Zone");
}

How would I return this "clubName" array to ensure the "choice -1" is used

I wanted to pass the "result" of "You Chose : abc" to a return type, so I can then pass it into my serialized method, so that I can then serialize that chosen team. I know how to return an array, but how would I return an array -1 ?
Code snippets are as follows :
public class Display{
public String[] printGreeting(int choice, String[] clubName) {
result = clubName;
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
if (choice >= 1 && choice <= 20) {
System.out.println("You chose: " + clubName[choice - 1]); // return the clubName -1
}
return result; // how to declare return statement ?
}
}
Here is my serialize code, not sure how I would pass the array, via an alias or use object ?
public class Serialize
{
public void Serialize() // receive return type from printGreeting();
{
// how to put object info into files, rather than declare here ?
try
{
FileOutputStream fileOut = new FileOutputStream("/home/cg/root/club.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(club);
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in C:/tmp/club.ser");
}catch(IOException i)
{
i.printStackTrace();
}
}
}
Any help with this would be greatly appreciated :)
Here you declare to return an array of String[]:
public String[] printGreeting(int choice, String[] clubName) {
// ↑ here you say this method MUST return an array if Strings
What you need is
assign the user's choice to returned variable
return just ONE String
public String printGreeting(int choice, String[] clubName) {
result = clubName;
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
if (choice >= 1 && choice <= 20) {
// assign choice to result
result = clubName[choice - 1];
// print choice
System.out.println("You chose: " + result); // return the clubName -1
}
// return the chosen club name
return result;
}
Actually, I don't know why result is a class attibute (but i cannot see declaration), what does not make much sense if you want to return it, I will code the method as:
public String printGreeting(int choice, String[] clubName) {
System.out.println("\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); // ??
if (choice >= 1 && choice <= 20) {
choice --; // if choice is valid, get the array position.
// print choice
System.out.println("You chose: " + clubName[choice]);
return clubName[choice];
}
// if the choice is not correct, return null or "" as you want
return null;
}
UPDATE
Could anyone advise how I would pass that returned String to my serialize method, I think I know how to serialize it, but not 100% sure on parameter passing.
I don't get exactly what you want to achieve, maybe would be better to rephrase question with your target clear, and your tries.
Serialize (shortly), in Java is make an object's attributes convertible to Strings, then, a String either an String[] array does not need to be serialized.
As long as Display methods are not static, you must create an instance of Display to execute as follow:
public class Main {
public static void main(String [] args) {
// create an instance of Display class
Display d = new Display();
// get the needed values to pass to printGreeting method:
String[] clubs = {"club one", "club two" // put 20 clubs
// get the index from the user
Scanner sc = new Scanner(System.in);
System.out.print("Enter number 1: ");
while (!sc.hasNextInt()) sc.next();
int choice = sc.nextInt();
// call the method and get the return:
String result = d.printGreeting(choice, clubs)
// then get a serializer and execute method:
Serialize s = new Serialize();
s.serialize(result);
}
}
change the method Serialize.serialize() to Serialize.serialize(String) as follows:
public class Serialize
{
public void serialize(String club)
// ↑ receive return type from printGreeting();
{
// your serialize code
}
}
What do you want to return? The club name (String) or the whole array?
It's not clear in your code if result is an array or a String, you simply say result = clubName. If it's an array it should be String[] result = clubName;, if you want to return a String it should be String result = clubName[choice -1];, in that case you have to change the method to public String printGreeting(int choice, String[] clubName) and you can return result;

Retrive and compare int value from an ArrayList

good night. I'm trying to retrieve and compare an int variable value from an ArrayList (if that is possible) but no matter what I do it never works. I already tried methods like contains(), get() and others. My logic is really bad I guess, could someone help me ? Please?
public class Obras extends Books implements ILibrary {
protected ArrayList<Obras> ListObra = new ArrayList<Obras>();
protected String typeObra;
protected String statusBorrow;
protected int ISBNuser;
Scanner userInput = new Scanner(System.in);
Scanner tipoInput = new Scanner(System.in);
public void createnewObra()
{
System.out.println("Insert the type of the new item: [Book, article...");
typeObra = tipoInput.nextLine();
super.createnewObra();
}
....
public void addObra() {
Obras newObra = new Obras();
newObra.createnewObra();
ListObra.add(newObra);
System.out.println("> Uma nova obra foi adicionada com sucesso!\n");
....
public void BorrowObra() {
System.out.println("> Choose a book from the list: ");
showListObras();
System.out.println("\n\n> Please choose one of the items from the above list by typing it's ISBN value: ");
ISBNuser = opcaoInput.nextInt();.
if(ListObra.get(ISBN).equals(ISBNuser))
{
System.out.println("> You successfully borrowed this book");
statusBorrow = false;
}
To get an int from an ArrayList, your ArrayList would have to be defined along the lines of this:
ArrayList<Integer> arrayListOfIntegers = new ArrayList<Integer>();
or
List<Integer> listOfIntegers = new ArrayList<Integer>();
Your list appears to contain objects of class Obras.
Also, when you call ListObra.get(ISBN), this method is designed to return the object at the specified index within the list - I suspect ISBN is not an index in the list, rather an ISBN of a book?
On a separate note, try to stick to Java naming standards - variables start with lower case letters and methods use camel case (e.g. createNewObra()). It makes things easier for other developers to understand.
ListObra.get(ISBN).equals(ISBNuser)
to:
Obras o = ListObra.get(ISBN);
if (o != null && o.getISBNuser() == ISBNuser) {
System.out.println("> You successfully borrowed this book");
statusBorrow = false;
}
because you only get a object Obras and you doesn't Override equal function in Obras, so you need to get Integer ISBUser and equal to the user input.
Another Way:
Override equal:
public class Obras extends Books implements ILibrary {
#Override
public boolean equals(Object e) {
Integer i = (Integer)e;
if (this.ISBUser == i) return true;
return false;
}
}
so now can use equals function to compare:
ListObra.get(ISBN).equals(ISBNuser)

Linked List object is not storing string input which results in a blank Link list

I am having issues storing data typed in the keyboard to my link list Add method. The point of this program is to implement a queue using a linked list. The only thing is, that the class constructor accepts two parameters for every node in the list (their Name and link).
here is my class file so far...
public class linklist_MP
{
//Private intance variables and links
private linklist_MP front;
private linklist_MP rear;
private linklist_MP link;
private linklist_MP previous;
private String data;
private int count = 0;
private boolean flag;
//Construtor for Each Node's link and parameter type
public linklist_MP(String input, linklist_MP intiallink)
{
data = input;
link = intiallink;
}
public boolean listEmpty()
{
flag = false;
if(count == 0)
{
flag = true;
}
return flag;
}
public void addList(String input)
{
//Creating new node with read input
//linklist_MP node = new linklist_MP(input, null);
if(count == 0)
{
front = new linklist_MP(input, front);
}
else
{
previous = front;
while(previous.link != null)
{
previous = previous.link;
}
rear = previous;
rear.link = new linklist_MP(input, null);
}
count++;
}
public String toString()
{
String result = data + " ";
if (link != null)
{
result += link.toString();
}
return result;
}
}
And Here is my Driver File which makes a object of my class and stores in the user data..
import java.io.*;
import java.util.Scanner;
import java.util.StringTokenizer;
public class linklistDriver_MP
{
public static void main(String[] args)
{
String input;
Scanner keyboard = new Scanner(System.in);
System.out.println("Just add a String: ");
input = keyboard.nextLine();
linklist_MP object = new linklist_MP(input, null);
object.addList(input);
System.out.println("Add another String: ");
input = keyboard.nextLine();
object.addList(input);
System.out.println("\nTime to print the list out: ");
object.toString();
}
}
Basically when my print method is called in the driver file to print all the nodes in the link list, nothing comes out and the list prints blank. I am trying to figure out why that is since I used the object in my driver to add the two strings the user enters in the keyboard as the add method is called... Thanks in-advance!
The reason your program does not output anything is because you call the method toString() but you never print the output of this method.
However it looks as if your linked list structure is also way off. Essentially a linked list data structure consists of a piece of data and a link to the next node in the sequence.
You however have multiple other nodes linked in your node. You should try to simplify your design because a linked list is a very simple data structure but I think you have overcomplicated it.

Problems of checkName() and storing user input to ArrayList and boolean[]

Here I have a GUI window and it basically ask the user to select a JRadioButton and type something in a JTextField, then choose confirm/cancel.
It is a project which we have to make a UML-to-Java text file. User would enter class information and choose a UML relationship, and this programme have to print out the Java clsas text on a JTextField. Just like when you create a new class in eclipse.
what I want to do is make a boolean[] to store an array of booleans, when user selects JRadioButton_A it'll store true and when user select JRadioButton_B it'll store false.And also I want the things typed in JTextField to be checked by a checkName(), if the method returns false, the string will be stored in an ArrayList.
Below is my code - there's some problems in getName() method and the boolean[] for storing true and false. When user needs to input name again, it would save the discarded sting/boolean into the array. (Sorry for my bad english!) Is there any better way to make this programme? I feel like I am complicating things and there should be a simpler way to make it.
Here's the UI stuffs asking user to enter class information. User have to select public/private and then type in class name and JTextField
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
String name = inputClassName.getText();
classObject.addName(name);
while (classObject.checkName(name) == true){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end if
JOptionPane.showMessageDialog(null, "Class saved."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end actionPerformed()
}// end Handler class
private class Handler2 implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean b = true;
b = classObject.setPP();
}
}
private class Handler3 implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean b = false;
b = classObject.setPP();
}
}
Here's the methods for storing the inputs to the ArrayList and boolean[]
Scanner input = new Scanner(System.in);
JavaKeywords keyObject = new JavaKeywords();
private ArrayList<String> className = new ArrayList<String>();
private String name = new String();
private int size = className.size();
private Boolean[] bArray = new Boolean[size];
public boolean checkName(String name){
boolean check = true;
for (int i=0; i<=size; i++){
if (keyObject.containsKeyword(className.get(i)) || name.equals(className.get(i))){
boolean o = false;
check = o;
}// end if
}// end for
return check;
}// end checkName
public boolean setPP(){
boolean b = true;
return b;
}
public void addPP(Boolean[] bArray){
this.bArray = bArray;
for (int i=0; i>=size; i++){
bArray[i] = setPP();
}
}// add a Array of boolean. for className[i], its class type = item[i] in bArray.
// public = true, private = false
public String getPublicPrivate(){
String p = "";
for (int i =0; i<=size; i++){
if(bArray[i]=true)
p = "public";
else
p = "private";
}
return p;
}
Solved
Solution: store the string className and boolean isPrivate in a class and make the class into an ArrayList can save me from all the trouble. But then i faced anther problem, that is the checkName() doesn't work after I changed my code.
here is the ActionListener
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
VirtualClass virtualObject = new VirtualClass();
classObject.addClass(virtualObject);
String name = inputClassName.getText();
virtualObject.className = name;
if (classObject.checkName(name) == false){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // Always return "invalid" message
} else {
JOptionPane.showMessageDialog(null, "Class saved.");
name = inputClassName.getText();
virtualObject.className = name;
}
if (event.getSource() == publicButton) {
virtualObject.isPrivate = false;
} else if (event.getSource() == privateButton) {
virtualObject.isPrivate = true;
}
}// end actionPerformed()
and here is the checkName() method
public boolean checkName(String name){
boolean check = true;
for (int i=0; i<=size; i++){
if (keyObject.containsKeyword(classes.get(i).className) || name.equals(classes.get(i).className)){
boolean o = false;
check = o;
}// end if
}// end for
return check;
}// end checkName
For containsKeyword() in checkName() I've used a JavaKeywords class from How to check if the class name is valid? by #MrLore.
Probably what I would do is create a simple class to represent your fields so you don't have to use multiple lists at all.
public class VirtualClass {
public boolean isPrivate;
public String className = "Object";
}
ArrayList<VirtualClass> classes = new ArrayList<VirtualClass>(0);
public void addClass(VirtualClass clazz) {
classes.add(clazz);
}
Otherwise you will have to create a second list of some kind to hold the public/private. You will just have to change them in parallel.
// in actionPerformed
ClassObject.VirtualClass clazz = new ClassObject.VirtualClass();
clazz.isPrivate = rbPrivate.isSelected();
clazz.className = tfClassName.getText();
classObject.addClass(clazz);
And just ignore the listening on the radio buttons since you technically do not need their states until you go to add the class to the list.
To access the fields later you just need to
for (VirtualClass clazz : classes) {
System.out.println((clazz.isPrivate ? "private" : "public") + " " + clazz.className);
}
// or something like
for (int i = 0; i < classes.size(); i++) {
System.out.println(classes.get(i).className + ":");
if (classes.get(i).isPrivate) {
System.out.println(" private");
} else {
System.out.println(" public");
}
}
I'm not entirely convinced by your over all approach. What I think "should"/"could" happen is, the user enters all the information you ask, they hit "accept", you valid the information that the user has entered and if it is correct, you create a new object representing the results of this input as you need.
I would, personally, avoid using an array of booleans, or at least, expose them differently. The main problem I have with it is keeping it all straight in my head, what does the element at 0 actually mean?
Instead, I would provide getter/setters on the ClassName class that allowed me to set/get particular properties. You could, of course, keep the values in an array internally, but anyone using the class wouldn't need to know how you store these values.
The problem with your check name Handler is the fact you are blocking the Event Dispatching Thread with your while-loop
This will stop you program from responding to user input (and painting itself)
while (classObject.checkName(name) == true){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end if
Swing is a single threaded framework, meaning that all interactions and changes to the UI are expected to be executed within the context of the EDT. Equally, anything that blocks or stops this thread from processing the Event Queue, will stop it from responding to new events, including repaint requests, making your program hang
Instead, you should simply check the name within a if-else statement. If it's valid, create the new ClassName object, if it's not, display a message and let the method exit.
Check out Concurrency in Swing for more details

Categories