Java Encapsulation with arrays - java

So I have two classes one is called bag the other is called TestBag. The goal is to ask the user what they want: to add or remove, and show what they have in the cart.
I'm kinda new to encapsulation, and I don't know how to get the user input and put it in the add method and get that to go the the cart string to show what the user has in the cart. This is what I have so far. I'm doing the add part first before the remove.
bag class:
import java.util.Arrays;
class bag {
private String[] cart = new String[5];
private int add;
public String[] getcart(){
return Arrays.copyOf(cart, getcart().length);
}
public int getAdd(){
return add;
}
public void setAdd(int newValue){
add = newValue;
}
public void setcart(String [] cart){
cart = cart;
}
}
TestBag:
import java.util.Scanner;
public class TestBag {
public static void main(String[] args) {
bag obj = new bag();
System.out.println("Enter one of the following commands:");
System.out.println("1 - add");
System.out.println("2 - remove");
System.out.println("3 - exit");
Scanner input = new Scanner(System.in);
System.out.println();
System.out.println("Enter \"1\", \"2\" or \"3\"");
int choice =input.nextInt();
while (choice != 3) {
if(choice == 1) {
System.out.println("What do you want to add? ");
for (int i = 0 ; i < obj.setAdd.length; i++ ) {
obj.setAdd[i] = input.nextInt();
}
System.out.println("Here's whats in your cart: ");
printArray(obj.getcart());
}
else if(choice == 2) {
//remove
}
else if(choice == 3) {
//...exit program
}
else{
System.out.println("Enter \"1\", \"2\", \"3\"");
choice = input.nextInt();
}
}
}
}

Thank you for sharing your code. Looking at your bag class, you're trying to achieve encapsulation through data hiding:
Declare the variables of a class as private.
Provide public setter and getter methods to modify and view the variables values.
However, declaring the getters and setters that way exposes the variables you declared as private in the first step. Well, the getters are just fine since one really has to see the contents of the cart and the number of items in the cart. The setters are not fine. It's like declaring your variables as public since through the setters, you allow them to be modified at any time.
The main point of encapsulation through data hiding is to restrict access to the class's variables to selected methods. Here's how I'd go about it:
public class Bag{
//Assuming that the bag has a dynamic size, a list would be appropriate here
public List<String> items;
public Bag(){
items = new ArrayList<String>();
}
//This modifies the contents of the bag. The modification is restricted
//through one of the methods (adding an item into the bag)
//that are really part of the task.
public void add(String item){
items.add(item)
}
public List<String> getItems(){
return new ArrayList<String>(items);
}
public int getNumberOfItems(){
return items.size();
}
}

Related

How do i increment static variables in java

I'm very new to java but i have decent experience with c++ and python. So, I'm doing a question in which im required to implement an airplane booking system, which does the following -
1.initialize all seats to not occupied(false)
2.ask for input(eco or first class)
3.check if seat is not occupied
4.if seat is not occupied allocate seat else look for next seat
5.if economy seats are booked out, ask if user wants to bump up to first class
6.if user is negative display msg "next plane is in 3hrs"
but,
package oop;
import java.util.Arrays;
import java.util.Scanner;
public class AirplaneBooking {
private final static int MAX_ECO_SEATS = 5;
private final static int MAX_FIRST_CLASS_SEATS = 3;
private final static boolean[] ECO_SEATS = new boolean[MAX_ECO_SEATS];
private final static boolean[] FIRST_CLASS_SEATS = new boolean[MAX_FIRST_CLASS_SEATS];
private static int current_eco_seat = 0;
private static int current_first_class_seat = 0;
public static void initialilze_seats(boolean[] first_class_seats, boolean[] eco_class_seats){
Arrays.fill(first_class_seats, Boolean.FALSE);
Arrays.fill(eco_class_seats, Boolean.FALSE);
}
public static void display(boolean[] seats){
System.out.print("[");
for(boolean seat : seats){
System.out.print(seat + ",");
}
System.out.println("]");
}
public static void book_seat(boolean [] seats, int current_seat){
seats[current_seat] = true;
current_seat++;
System.out.println(current_seat);
}
public static int user_input() {
Scanner input = new Scanner(System.in);
System.out.print("Enter 1 for Economy class or 2 for First class : ");
int user_seat_prefrence = input.nextInt();
if (user_seat_prefrence == 1){
if(current_eco_seat < MAX_ECO_SEATS){
book_seat(ECO_SEATS, current_eco_seat);
}
else{
System.out.println("Looks like eco seats are full, would you like to book for first class insted(1/0) ?");
Scanner next_input = new Scanner(System.in);
int user_next_seat_prefrence = next_input.nextInt();
if (user_next_seat_prefrence == 1){
book_seat(FIRST_CLASS_SEATS, current_first_class_seat);
user_seat_prefrence = 2;
}
else{
System.out.println("next flight leaves in 3 hrs");
}
}
}
else if (user_seat_prefrence == 2){
if (current_first_class_seat < MAX_FIRST_CLASS_SEATS){
book_seat(FIRST_CLASS_SEATS, current_first_class_seat);
}
else{
System.out.println("Looks like first class seats are full, would you like to book economy instead?(1/0)");
int user_next_seat_prefrence = input.nextInt();
if (user_next_seat_prefrence == 1){
book_seat(ECO_SEATS, current_eco_seat);
user_seat_prefrence = 1;
}
else{
System.out.println("Next flight leaves in 3hrs");
}
}
}
else {
System.out.println("Enter valid option");
}
return user_seat_prefrence;
}
public static void print_boarding_pass(int user_seat_prefrence){
if (user_seat_prefrence == 1){
System.out.println("eco");
System.out.println(current_eco_seat - 1);
}
else{
System.out.println("first class");
System.out.println(current_first_class_seat - 1);
}
}
public static void main(String args[]){
initialilze_seats(FIRST_CLASS_SEATS, ECO_SEATS);
display(FIRST_CLASS_SEATS);
display(ECO_SEATS);
while(true){
int user_seat_prefrence = user_input();
print_boarding_pass(user_seat_prefrence);
display(FIRST_CLASS_SEATS);
display(ECO_SEATS);
System.out.print("book another seat:");
Scanner choice = new Scanner(System.in);
boolean book_another_seat = choice.nextBoolean();
if (book_another_seat == false)
break;
}
}
}
The problem i'm having with this code is if the seats for eco class(for example) are full, the program is supposed to ask if i want to book for first class instead and wait for my input, if I press 1 it should book in first class but the program does not await for my input and proceeds to else statement instead.
Also, i use a static variable current_eco_seat and current_first_class_seat to keep track of the current seat being booked, and i pass that static variable to book_seat function, the program then books the seat and increments the current_eco_seat or current_first_class_seat(depending which is passed) so that next seat can be booked in next interation. But the static variable does not get incremented at all.
These are the only problems i have with the program.
Any help is appreciated, thanks
As Java calls methods by value,
Your problem about static is you are passing the value of current_seat to the book_seat method, so changing the value doesn't affect that variable after returning from the method.
To solve it just call the method and do not pass your static vars. It's static, so you have access it from everywhere.
i.e:
public static void book_seat(boolean [] seats){
seats[current_seat] = true;
current_first_class_seat++;
System.out.println(current_seat);
}
Checking Inout stream
Not sure wether your question is related to "static" variables or more related to "How to handle Input Stream?".
Regarding:
if I press 1 it should book in first class but the program does not await for my input and proceeds to else statement instead.
You should think about "flushing" the Input Stream before reading again. flush-clear-system-in-stdin-before-reading
Method Parameter usage
On the other hand this method is wrong
public static void book_seat(boolean [] seats, int current_seat){
seats[current_seat] = true;
current_seat++;
System.out.println(current_seat);
}
this command has no affect, but printing an information to the User. The variable you used in the caller "current_eco_seat" will not change at all.
you don't need to insist incrementing the exact variable, just do the following :
make book_seat() to return incremented value
public static int book_seat(boolean [] seats, int current_seat) {
seats[current_seat] = true;
System.out.println(current_seat + 1);
return current_seat + 1;
}
set returned value to current_first_class_seat or current_eco_seat
if (current_first_class_seat < MAX_FIRST_CLASS_SEATS){
current_first_class_seat = book_seat(FIRST_CLASS_SEATS, current_first_class_seat);
}
else{
System.out.println("Looks like first class seats are full, would you like to book economy instead?(1/0)");
int user_next_seat_prefrence = input.nextInt();
if (user_next_seat_prefrence == 1){
current_eco_seat = book_seat(ECO_SEATS, current_eco_seat);
user_seat_prefrence = 1;
}
else{
System.out.println("Next flight leaves in 3hrs");
}
}
Then you can use book_seat() for both eco and first class reservations handling as previously you have intended.

How to add data into array in another class in Java?

[EDIT: I've solved the problem. I just need to make the arrays static. I can't believe I didn't of that. Thanks for everyone's help!]
I have a bookstore program where people can buy a maximum of 5 different books. Once they choose a title, it will be added to an array for the invoice later. Choosing the titles and putting it into the array is in 2 different classes. Just for trial, I'm buying 2 books: Athletics and Autosport.
Expected output:
You bought 2 book(s)!
1) Athletics Weekly Magazine
2) Autosport Magazine
Edited List.java: I've tried both things. First is changing to i-1
In SportsMag.java:
import java.util.Scanner;
public class SportMag extends Magazine{
Scanner scan = new Scanner(System.in);
public void title() {
System.out.println("");
System.out.println("What do you want to buy?");
System.out.println("1. Athletics Weekly");
System.out.println("2. Autosport");
int choice = scan.nextInt();
List l = new List();
if (choice==1) {
l.totalbooks(1);
l.booknames(1,"Athletics Weekly", "Magazine");
} else {
l.totalbooks(1);
l.booknames(1,"Autosport", "Magazine");
}
System.out.println("Do you want to go back to menu? (Yes/No)");
String back = scan.next();
if (back.equalsIgnoreCase("Yes")) {
BookType b = new BookType();
b.bookMenu();
}
if (back.equalsIgnoreCase("No")) {
l.printInvoice();
}
}
}
In List.java (where I print the invoice):
public class List {
static int total=0;
public void totalbooks(int num) {
total+=num;
}
String[] bookname = new String[5];
String[] booktype = new String[5];
static int a=0;
public void booknames(String newBookName, String newBookType) {
bookname[a]=newBookName;
booktype[a]=newBookType;
a++;
}
public void printInvoice() {
System.out.println("You bought "+total+" book(s).");
for (int i=0; i<total; i+=1) {
System.out.println((i+1)+") "+bookname[i]+" "+booktype[i]);
}
}
}
The output for this is:
You bought 2 book(s).
1) null null
2) Autosport Magazine
I also tried using ArrayList:
In SportMag.Java:
//same as above, only a little difference here
List l = new List();
if (choice==1) {
l.totalbooks(1);
bookname.add("Athletics Weekly");
} else {
l.totalbooks(1);
bookname.add("Autosport");
}
In the List.java:
ArrayList<String> bookname = new ArrayList<String>();
public void printInvoice() {
System.out.println("You bought "+total+" book(s).");
for (int i=0; i<total; i+=1) {
System.out.println(bookname.get(i));
}
}
I got an error in the SportMag.java that says bookname cannot be resolved. A quick fix offered was to create a local variable bookname but then it won't go to the array in List.java
I haven't learned about ArrayList so I'm not really sure what to do here.
I also tried making another version where everything is in the main method and only calls the methods in other classes to display the titles, not actually scanning the input in the other methods. I did this so that no objects die after each functions. The main became really long tho.
I don't know if this works fine for 2 books because I can't loop since everything is in the main.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
BookType b = new BookType();
List l = new List();
b.bookMenu();
int booktypechoice = scan.nextInt();
if (booktypechoice ==1) {
Magazine mag = new Magazine();
mag.magtype();
int magtypechoice = scan.nextInt();
if (magtypechoice==1) {
SportMag smag = new SportMag();
smag.title();
int smagchoice = scan.nextInt();
SportMag sportmag = new SportMag();
if (smagchoice==1) {
l.totalbooks(1);
l.booknames("Athletics Weekly", "Magazine");
System.out.println("Do you want to go back to menu? (Yes/No)");
String goback = scan.next();
if (goback.equalsIgnoreCase("Yes")) {
b.bookMenu();
}
if (goback.equalsIgnoreCase("No")) {
l.printInvoice();
}
} else {
l.totalbooks(1);
l.booknames("Autosport", "Magazine");
System.out.println("Do you want to go back to menu? (Yes/No)");
String goback = scan.next();
if (goback.equalsIgnoreCase("Yes")) {
b.bookMenu();
}
if (goback.equalsIgnoreCase("No")) {
l.printInvoice();
}
}
} else {
//all the other book choices goes here.
//It's really long, but it's just like sportmag up there
}
}
}
}
How do I input the book names into the array and have it displayed correctly?
I think you are having trouble with the scope of the variable List l. You create this variable inside the function title and you work with it, inserting in it the product the client requested. But then, where does the variable go from there? It just dies out at the end of the function. This object should be in a scope that will exist for as long as it is interesting.
For exemple, you can transform this variable into a property of your main class. It can be even a static class. You should find the better way to preserve your List object. As it is, it is dying as soon as the title function ends.

How to Add Duplicate Values to an ArrayList

I have a shopping list that contains a set number of items. Through user input, I want to ask the user how many of the same item would they like to add to their shopping bag.
For Example: I have the following ArrayList newProduct = {"apple","orange","banana"};. Now I want to prompt the user to choose which (and how many) of the items in newProduct would they like to add into a second array called bag. If the user chooses a an apple with a quantity of 2, then 2 apples would be added to bag and it would look like this bag = {"apple","apple"};
I tried to useoperands that would duplicate the value. But it didn't work very well. What is wrong with this?
import java.util.*;
import java.util.stream.IntStream;
public class Bag extends Price {
static Scanner input = new Scanner(System.in);
#SuppressWarnings("unused")
private static String newName;
private int choice;
public ArrayList<String> bag = new ArrayList<String>();
public List<Double> bagPrice = new ArrayList<Double>();
public void addProduct() {
Bag item = new Bag();
while (sum(bagPrice) <= 58.00) {
System.out.println("Choose a Priority");
item.choice = input.nextInt();
System.out.println("Choose Quantity");
int quantity = input.nextInt();
if (IntStream.of(newPriority).anyMatch(x -> x == item.choice)) {
item.bag.add(newProduct.get(item.choice));
System.out.print("PRICE $ " + Double.valueOf(formatter.format(price.get(item.choice - 1))));
bagPrice.add(price.get(item.choice - 1));
System.out.println("BAG: " + item.bag);
System.out.println("TOTAL : " + Double.valueOf(formatter.format(sum(bagPrice))));
} else {
System.out.println("Priority Does Not Exist");
}
}
}
public double sum(List<Double> bagPrice) {
double sum = 0.00;
for (double s : bagPrice) {
sum = sum + s;
}
return sum;
}
}
I'm fairly new to programming so if there is any better suggestion I would greatly appreciate it.
You might have to use clone() method to get a copy, hope this would be helpful Clone method for Java arrays

Creating a Creature App with Java, Object oriented and Constructors.

newbie here at Java. I'm working on a project to where I collect info from a user for two types of Creatures. The menu would look like:
1. Land based
2. Water based
3. Display Animal
4. Quit.
I'm wanting to collect the user information from the user and then display it back to them. I think I'm stuck on building the object constructors from the different object.
Here's what I have so far:
SuperClass:
package com.animal;
public class Creature {
private String size;
private String weight;
public Creature (String size, String weight){
this.size = size;
this.weight = weight;
}
public String getSize() {return size;}
public void setSize(String size) {this.size = size;}
public String getWeight() {return weight; }
public void setWeight(String weight) {this.weight = weight; }
void displayCr(){
System.out.println("***Creatures***");
System.out.println("Size: " + size);
System.out.println("Weight: " + weight);
This is my Land Subclass:
package com.animal;
public class Land extends Creature {
private String landAnimal;
public String getLandAnimal() {return landAnimal;}
public void setLandAnimal(String landAnimal) {this.landAnimal = landAnimal;}
public Land(String size, String weight, String landAnimal) {
super(size, weight);
this.landAnimal = landAnimal;
This is my Water subclass:
package com.animal;
public class Water extends Creature {
private String fish;
public String getFish() {return fish;}
public void setFish(String fish) {this.fish = fish;}
public Water(String size, String weight, String fish) {
super(size, weight);
this.fish = fish;
}
Then this is my Main called Kingdom:
package com.animal;
import java.util.ArrayList;
import java.util.Scanner;
public class Kingdom {
public static void main(String[] args) {
ArrayList<Creature> user = new ArrayList<Creature>();
Scanner input = new Scanner(System.in);
int selection = 0;
while(selection != 4){
System.out.println("****Main Menu****");
System.out.println("Enter 1 for Land Animal");
System.out.println("Enter 2 for Water Animal");
System.out.println("Enter 3 to Display Animal");
System.out.println("Enter 4 to quit");
selection = input.nextInt();
if(selection==1 || selection==2){
Creature userInfo = null;
System.out.println("Enter Size ");
String size = input.next();
System.out.println("Enter Weight: ");
String weight = input.next();
}
if(selection == 1){
System.out.println("Enter Land animal type: ");
String landAnimal = input.next();
//userInfo = new Land(size, weight, landAnimal);
//user.add(userInfo);
}
else if(selection == 2){
System.out.println("Enter Water animal type: ");
String fish = input.next();
//userInfo = new Water(size, weight, fish);
}
//creature.add(userInfo);
//System.out.println(user.displayCr());
}
I feel like I'm on the right path, but the last steps just aren't clicking for me and I've been grinding on this, reading, videos and nothing is clicking.
Also, I apologize if I've made the newbie mistakes in this post. I will accept all criticism, suggestions and help as a positive lesson. Thanks.
Overall your code is fairly right.
Except:
Creature userInfo = null; you are defining it inside the first IF, its scope will be limited to that IF.
As soon as you leave that IF it ceases to exist, hence you can't use it in the following IFs.
Consider the following scope change:
if(selection==1 || selection==2){ // main IF
Creature userInfo = null;
...
if(selection == 1){
...
}
else {
...
}
System.out.println(userInfo.displayCr());
} // end of main IF
First of all expand the scope of size,weight and userInfo means keep it inside main but outside the conditions as it is being used everywhere. Something like this.
int selection = 0;
String size = null;
String weight = null;
Creature userInfo = null;
Instead of this
creature.add(userInfo); should be
user.add(userInfo);
and call display like this
userInfo.displayCr(); because the return type of the method is void so cannot be used inside sysout and it should be inside that else if(){}

Creating and Returning Values from an ArrayList in Java

I'm working on an assignment for a low-level java class. I have it mostly finished, but I'm stuck on how to use an ArrayList. There are two classes, the second one (PizzaMaker) is the client. I need to initialize an ArrayList in the first class and then add three items to it via user input from the client. I know how to initialize the ArrayList, but I'm having problems adding items to the list. When I run the code I have now, it returns with empty brackets [ ] or null.
I'm not expecting someone to do my homework for me, but a clue as to where I'm going wrong with this code would be helpful.
import java.util.*;
public class Pizza {
private String brand;
private int size;
private ArrayList<String> toppings = new ArrayList<String>();
public Pizza(String brand, int size) {
this.brand = brand;
this.size = size;
}
public void changeBrand(String brandName) {
brand = brandName;
}
public void changeSize(int pizzaSize) {
size = pizzaSize;
}
public void addTopping(String topping) {
toppings.add("topping");
}
public String getPizzaInfo() {
String result = "You want a "+ size +" inch pizza made by: "+ brand +" with these
toppings:" + toppings;
return result;
}
}
public class PizzaMaker {
public static void main( String[] args) {
int size = -1;
String brand = "";
String topping = "";
brand = getBrand();
size = getSize();
topping = getTopping();
Pizza newPizza = new Pizza(brand, size);
System.out.println(newPizza.getPizzaInfo());
}
public static String getBrand() {
Scanner kb = new Scanner(System.in);
System.out.println("Enter a brand name: ");
String brandName = kb.nextLine();
return brandName;
}
public static int getSize() {
Scanner kb = new Scanner(System.in);
System.out.println("Enter a size: ");
int pizzaSize = kb.nextInt();
kb.nextLine();
return pizzaSize;
}
public static String getTopping() {
Scanner kb = new Scanner(System.in);
System.out.println("Enter topping: ");
String topping = kb.nextLine();
return topping;
}
public static boolean getAgain() {
return true;
}
}
You need to call addTopping. Eg, newPizza.addTopping(topping). Also, correct the addTopping method. Replace toppings.add("topping") with toppings.add(topping);
And I am sure you need to put more effort to learn Java :)
You never added any toppings to your pizza,
Pizza newPizza = new Pizza(brand, size);
// Keep adding toppings, check for empty string to end?
while ((topping = getTopping()).length() > 0) {
newPizza.addTopping(topping); // <-- add the topping to the pizza.
}
System.out.println(newPizza.getPizzaInfo());
You also need to fix your method addTopping
public void addTopping(String topping) {
// toppings.add("topping");
toppings.add(topping);
}
As you specifically asked not to have us do your homework for you (which is good :) ) I will only give you the clues and pseudocode for what you need to do:
Right now you are just creating the Pizza object in PizzaMaker, but you are not doing anything with it. You have already created the methods to retrieve the toppings in PizzaMaker, the method getTopping(). You also have the method to add the toppings to the pizza in Pizza which is addTopping(). Now you just need to call the methods from PizzaMaker so they will be used.
The psuedocode should be like this:
Create the pizza object
For the number of toppings you want to add call getTopping()
For each topping you get you need to add that topping to you Pizza object with your addTopping() method.
Once all the toppings have been added, you can print out your pizza object.
It looks like you want to be able to ask the user for multiple toppings. So as a first approximation, let's assume the topics are single word only, separated by commas (something easy to test using the Scanner you have set up). I recommend two changes to your source code:
First, change the ArrayList of toppings to be called toppingList
private ArrayList<String> toppingList = new ArrayList<String>();
Next, change the addToppings(String toppings) to break the tuple entered by the user into tokens (delimited by spaces):
public void addToppings(String toppings) {
// Let's assume the user enters all toppings as single words delimited
// / by space
StringTokenizer strtok = new StringTokenizer(toppings);
while (strtok.hasMoreTokens()) {
String topping = strtok.nextToken();
toppingList.add(topping);
}
}
Lastly, you will need to call the addToppings method from your main program:
public static void main(String[] args) {
int size = -1;
String brand = "";
String topping = "";
brand = getBrand();
size = getSize();
topping = getTopping();
Pizza newPizza = new Pizza(brand, size);
newPizza.addToppings(topping);
System.out.println(newPizza.getPizzaInfo());
}
One final note: make sure to close your Scanner instances, or you will have a resource leak. It's okay for this simple program, but if it were long-running, you have memory leaks.
To beef up your program, you could try:
Use a different delimiter, allowing multiple words in your toppings (like "Canadian Bacon" - two words),
Modify the getTopping() method to ask for the toppings one-at-a-time until the user presses some special key ("q to quit" is always a good one).
Have fun!
First mistake is you are not calling the methods you have defined in Pizza Class.
You are simply passing by constructor and initilizing the class variable and displaying those variable, but you are not passing the tropping value by constructor.
These below methods you are not calling anywhere .
/*public void changeBrand(String brandName) {
brand = brandName;
}
public void changeSize(int pizzaSize) {
size = pizzaSize;
}*/
Just Use this below code:-
public static void main( String[] args) {
int size = -1;
String brand = "";
String topping = "";
brand = getBrand();
size = getSize();
topping = getTopping();
Pizza newPizza = new Pizza(brand, size);
newPizza.addTopping(topping);
System.out.println(newPizza.getPizzaInfo());
}
Output :-
Enter a brand name:
Manoj
Enter a size:
20
Enter topping:
pizaset 1
You want a 20 inch pizza made by: Manoj with these toppings:[pizaset 1]
Hope it will help you.
Its working now, I have tested.

Categories