I have 3 classes:
Sportswear (superclass)
Jersey (subclass)
Driver
I have an ArrayList in my driver to hold all my jerseys created.
When the user inputs all the values (stock, price, product, team, kit, size, gender),
and it displays them back it shows null :
Product: null
In stock: 0
Price: 0
Team:
Kit:
Size:
Gender:
The superclass (Sportswear) has the variables stock, price and product (so I can include other products, not just jerseys)
And the subclass (Jersey) contains the variables team, kit, size, gender. It also contains the method jerseyDisplay() which shows what is above.
In the driver after the values are inputted I put:
Jersey jersey = new Sportswear(stock, price, product, team, kit, size, gender);
sportswear.add(jersey);
jersey.jerseyDisplay();
Is this completely wrong? Why arn't the inputted values showing up?
The jerseyDisplay() method in the subclass Jersey is:
public void jerseyDisplay()
{
super.sportswearDisplay();
System.out.println("Team: "+team);
System.out.println("Kit: "+kit);
System.out.println("Size: "+size);
System.out.println("Gender: "+gender);
}
#DessertIvy This is the Sportswear superclass:
public class Sportswear
{
//instance variables
private int stock;
private float price;
private String product;
//blank constructor
public Sportswear()
{
this.stock = 0;
this.price = 0;
this.product = "";
}
//detailed constructor
public Sportswear(int s, float p, String pd)
{
this.stock = stock;
this.price = price;
this.product = product;
}
//setters
public void setStock(int stock)
{
this.stock = stock;
}
public void setPrice(float price)
{
this.price = price;
}
public void setProduct(String product)
{
this.product = product;
}
//getters
public int getStock()
{
return stock;
}
public float getPrice()
{
return price;
}
public String getProduct()
{
return product;
}
//increase stock
public int increaseStock()
{
stock = stock++;
return stock;
}
//decrease stock
public int decreaseStock()
{
stock = stock - 1;
return stock;
}
public void sportswearDisplay()
{
System.out.println("Product: "+product);
System.out.println("In stock: "+stock);
System.out.println("Price: "+stock);
}
}
The constructor in the Jersey subclass:
public Jersey(int stock, float price, String product, String team, String kit, String size, String gender)
{
super(stock, price, product);
this.team = "";
this.kit = "";
this.size = "";
this.gender = "";
}
The problem are within your 2 contructors :
//detailed constructor
public Sportswear(int s, float p, String pd)
{
this.stock = stock;
this.price = price;
this.product = product;
}
and
public Jersey(int stock, float price, String product, String team, String kit, String size, String gender)
{
super(stock, price, product);
this.team = "";
this.kit = "";
this.size = "";
this.gender = "";
}
You should initialize your variables with the values passed as parameters... or use your setXXX methods. In the constructor, it should look like this :
//detailed constructor
public Sportswear(int s, float p, String pd)
{
this.stock = s;
this.price = p;
this.product = pd;
}
Also, as mentionned earlier, this line
Jersey jersey = new Sportswear(stock, price, product, team, kit, size, gender); shouldn't even compile... you probably meant Jersey jersey = new Jersey(stock, price, product, team, kit, size, gender);
Related
So i'm making a supermarket program that allows to add products and sell them, so far i have this:
class Product
{
String name;
double price;
int day;
int month;
int year;
int stock;
public Product(String name,double price,int day,int month,int year,int stock)
{
this.name=name;
this.price=price;
this.day=day;
this.month=month;
this.year=year;
this.stock=stock;
}
}
class SuperMarket{
protected String name;
protected int numMax;
private List<Product> pr;
public SuperMarket(String name,int numMax)
{
this.name=name;
this.numMax=numMax;
this.pr = new ArrayList<Product>();
}
public void addProduct() {
//deleted to post here
}
public void sellProduct()//its here i need help
{
Scanner sc=new Scanner(System.in);
System.out.println("What product do you want to sell?");
String name=sc.nextLine();
}
}
I´d like to know how to search in Product list by name and then change the stock(subtract-n) to sell n of that product.
You can use Stream API to find out the product by name. Filter the list by checking the name of product and get first match.
Optional<Product> product = productList.stream()
.filter(e -> e.name.equals(inputedName))
.findFirst();
Then can check is product found then update the stock
if(product.isPresent()){
Product p = product.get();
p.stock = p.stock - numberOfSoldProduct;
}
Suggestion to use getter/setter for fields.
In case if you are looking to get search using O(1), you can use map. however i don't see necessary of list though.
public SuperMarket(String storeName,int storeId){
this.storeName = storeName;
this.storeId = storeId;
this.products = new ArrayList<Product>();
this.productByName = new HashMap<String, Product>();
}
public void addProduct(Product product) {
String productName = product.name;
if(productByName.containsKey(productName)){
Product existingProduct = productByName.get(productName);
existingProduct.stock += product.stock;
existingProduct.price = product.price;
}else{
productByName.put(productName, product);
products.add(product);
}
}
public void sellProduct(String productName, int count){
if(!productByName.containsKey(productName)){
System.out.println(productName + " is unavailable !!!");
return;
}
Product existingProduct = productByName.get(productName);
existingProduct.stock -= count;
if(existingProduct.stock <= 0){
productByName.remove(productName);
products.remove(existingProduct);
}
}
}
I am writing a simple inventory system for practice and I have an item class that holds these values:
private String name;
private int quantity;
private Integer ID;
private Double pricePerUnit;
private Double totalPrice;
I am writing the constructors for this class and I want everything except the name and quantity to be optional, as in the user can opt whether or not to input any data for those fields. Currently I have two constructors that look like this:
public Item(String name, int quantity)
{
this.name=name;
this.quantity=quantity;
}
public Item(String name, int quantity, Integer ID, Double pricePerUnit, Double totalPrice)
{
this(name, quantity);
this.ID=ID;
this.pricePerUnit=pricePerUnit;
this.totalPrice=totalPrice;
}
Is there any way I can make some of the arguments in the second constructor optional, or non-mandatory?
Thanks!
Naturally, in such cases I'd would think of two possibilities to get what you need, Constructor Overloading and Builder Pattern
Although when you have the same data formats, You can't naturally depend on the former. In such cases (as OP's Question) the best alternative is to go for a builder design pattern.
You can build an instance of Item.class as the following
public class Item {
\\... other public functions.. etc
static class ItemBuilder{
private Item item;
public ItemBuilder withNameAndQuantity(String name, int quantity){
item = new Item(); //default constructor or as per your usecase a private constructor
item.setName(name);
item.setQuantity(quantity);
return this;
}
public ItemBuilder withPricePerUnit(Double pricePerUnit){
if(item!=null){
item.setPriceUnit(pricePerUnit);
}
return this;
}
public ItemBuilder withTotalPrice(Double totalPrice){
if(item!=null){
item.setTotalPrice(totalPrice);
}
return this;
}
public Item build(){
if(item!=null){
return item;
}else{
throw new IllegalStateException("item is null, no name or id set");
}
}
}
}
Finally, you could build a new Item by doing the following :
Item item = new Item.ItemBuilder(). withNameAndQuantity("apple",10). withTotalPrice(100).build();
Ideally you would decompose the class into coherent pieces, in much the same way as you might normalise a database schema.
There is the Builder Pattern.
You code could be written better by making the constructor will all the attributes the "canonical constructor* and forward to that. This will also make it easier to switch over to records when they become available.
public Item(String name, int quantity) {
this(name, quantity, null, null, null);
}
public Item(String name, int quantity, Integer id, Double pricePerUnit, Double totalPrice) {
this.name = name;
this.quantity = quantity;
this.ID = ID;
this.pricePerUnit = pricePerUnit;
this.totalPrice = totalPrice; // Shouldn't this be calculated?
}
(Not that nulls are ideal.)
One way is to create more constructors and another is to loose the immutability and introduce setter methods.
Hence, you can use Builder Pattern as Builder Pattern will help you to consume additional attributes while retaining the immutability of Item class.
Below is the coded solution. This uses a additional class ItemBuilder which helps us in building desired Item object with all mandatory attributes and combination of optional attributes, without loosing the immutability.
public class Item {
//All final attributes
private String name; // required
private int quantity; // required
private Integer ID; // optional
private Double pricePerUnit; // optional
private Double totalPrice; // optional
private Item(ItemBuilder builder) {
this.name = builder.name;
this.quantity = builder.quantity;
this.ID = builder.ID;
this.pricePerUnit = builder.pricePerUnit;
this.totalPrice = builder.totalPrice;
}
//All getter, and NO setter to provide immutability
public String getName() {
return name;
}
public int getQuantity() {
return quantity;
}
public Integer getID() {
return ID;
}
public Double getPricePerUnit() {
return pricePerUnit;
}
public Double getTotalPrice() {
return totalPrice;
}
#Override
public String toString() {
return "User: "+this.name+", "+this.quantity+", "+this.ID+", "+this.pricePerUnit+", "+this.totalPrice;
}
public static class ItemBuilder
{
private String name; // required
private int quantity; // required
private Integer ID; // optional
private Double pricePerUnit; // optional
private Double totalPrice; // optional
public ItemBuilder(String name, int quantity) {
this.name = name;
this.quantity = quantity;
}
public ItemBuilder ID(Integer ID) {
this.ID = ID;
return this;
}
public ItemBuilder pricePerUnit(Double pricePerUnit) {
this.pricePerUnit = pricePerUnit;
return this;
}
public ItemBuilder totalPrice(Double totalPrice) {
this.totalPrice = totalPrice;
return this;
}
//Return the finally constructed Item object
public Item build() {
Item item = new Item(this);
validateUserObject(item);
return item;
}
private void validateUserObject(Item item) {
//Do some basic validations to check
//if item object does not break any assumption of system
}
}
}
OR
You can also make use of JsonProperties.
#JsonIgnoreProperties(ignoreUnknown = true)
public record Item(
String name,
Integer quantity,
#JsonInclude(JsonInclude.Include.NON_NULL) Integer ID,
#JsonInclude(JsonInclude.Include.NON_NULL) Double pricePerUnit,
#JsonInclude(JsonInclude.Include.NON_NULL) Double totalPrice) {}
I hope this gives you clarity on how to resolve your problem.
I cannot get the Product Objects to print out anything using an Enhanced for loop. Everything comes out null or 0?
The output show this?
0null0.0This is the id
0null0.0This is the id
0null0.0This is the id
Here's my code:
class Main {
public static void main(String[] args) {
System.out.println("Hello world!");
ArrayList < Product > store1 = new ArrayList < Product > ();
store1.add(new Product(3, "Nike", 300.0));
store1.add(new Product(2, "Addidas", 400.0));
store1.add(new Product(6, "Under Armor", 500.0));
for (Product y: store1) {
System.out.println(y + "This is the id");
}
}
}
class Product {
public int id;
public String name;
public double price;
public Product(int startId, String startName, double startPrice) {
startId = id;
startName = name;
startPrice = price;
}
public int getId() {
return id;
}
public double getPrice() {
return price;
}
public String getName() {
return name;
}
public String toString() {
return id + name + price;
}
}
You are doing a backward assignments in the constructor:
public Product(int startId, String startName, double startPrice) {
startId = id;
startName = name;
price = startPrice;
}
leaving the object uninitialized...
but you mean for sure
public Product(int startId, String startName, double startPrice) {
id = startId;
name = startName;
startPrice = price;
}
You have your assignments backward in the constructor. It should be:
public Product(int startId, String startName, double startPrice) {
id = startId; // Not `startId = id;`
name = startName; // Not `startName = name;`
price = startPrice; // Not `price = startPrice;`
}
or better yet (and this would have flagged the problem up for you when you tried to compile), don't rely on implicit this:
public Product(int startId, String startName, double startPrice) {
this.id = startId;
this.name = startName;
this.price = startPrice;
}
You are setting the variables the wrong way around in your constructor, i.e.
startId = id; should be id = startId;
You should also add #Override to your toString() method.
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 8 years ago.
Improve this question
Good day to everyone
I'm new here and in Java, and this is one of first programs with 4 classes and simple methods.
In this prog we put our deal from keybord(we put buyer, seller names, title, price and quantity of products buyed). And so, after I input 2 deals and program must give output I get NullPointerException.
Application.java
package ua.lviv.my;
import java.util.Scanner;
public class Application {
private static Deal [] deal = new Deal[2];
public static void main(String[] args) {
new Application().allActions();
}
void allActions(){
input();
System.out.println("======================");
output();
}
public void output(){
for(int i=0; i<deal.length; i++){
System.out.println("Buyer :" +deal[i].getBuyer().getName());
System.out.println("Seller :" +deal[i].getSeller().getName());
for (int j = 0; j < deal[i].getProducts().length; j++) {
System.out.println("Buys " +deal[i].getProducts()[j].getTitle() +"for " +deal[i].getProducts()[j].getPrice() + " in quantity " +deal[i].getProducts()[j].getQuantity());
}
}
}
public void input(){
for (int i=0; i<deal.length; i++){
deal[i]=inputDeal();
}
}
public Members inputMember(String msg){
Members members = new Members();
String memberName = keybordIn(msg);
members.setName(memberName);
return members;
}
public Product inputProduct(){
Product product =new Product();
String titleStrng = keybordIn("Enter product title");
String priceStrng = keybordIn("Enter product price");
String quantityStrng = keybordIn("Enter quantity");
double price=Double.parseDouble(priceStrng);
int quantity = Integer.parseInt(quantityStrng);
product.setTitle(titleStrng);
product.setPrice(price);
product.setQuantity(quantity);
product.getCost(price, quantity);
return product;
}
public Deal inputDeal(){
Members buyer = inputMember("Enter buyer name :");
Members seller =inputMember("Enter seller name :");
Product [] products = new Product[2];
for(int i=0; i<products.length; i++){
products [i]=inputProduct();
}
Deal deal = new Deal(buyer, seller, products);
return deal;
}
public String keybordIn(String msg){
System.out.println(msg);
Scanner scan = new Scanner(System.in);
String in = scan.next();
return in;
}
}
Deal.java
package ua.lviv.my;
import java.util.Date;
public class Deal {
private Date date = new Date();
private Members buyer;
private Members seller;
private Product[] products = new Product[2];
public Deal(Members buyer, Members seller, Product[] products) {
}
public Date getDate() {
return date;
}
public Members getBuyer() {
return buyer;
}
public Members getSeller() {
return seller;
}
public Product[] getProducts() {
return products;
}
public double inTotal() {
double summ = 0;
for (int i = 0; i < products.length; i++) {
summ += products[i].getCost(products[i].getPrice(),
products[i].getQuantity());
}
return summ;
}
}
Members.java
package ua.lviv.my;
public class Members {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package ua.lviv.my;
public class Product {
private String title;
private double price;
private int quantity;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
public double getCost(double price, int quantity){
double cost = price*quantity;
return cost;
}
}
Start by taking a look at the constructor for Deal...
public Deal(Members buyer, Members seller, Product[] products) {
}
You never assign any of the values passed via the constructor to the member fields, for example...
public Deal(Members buyer, Members seller, Product[] products) {
this.buyer = buyer;
this.seller = seller;
this.products = products;
}
I have an inventory program written to include an array and a method to calculate total cost for all inventory items entered. I now have to include a subclass that overrides the original to include "one unique feature". I created a new file named ItemDetails to set up for the subclasses of the original Item. I need to include one unique feature and calculate the value of the inventory and calculate a 5% restocking fee in this subclass. Do I just transfer some of the relevant lines into the other class? Or do I write some code twice? I don't know what to do next. Any help is useful. Thanks. This is what I have so far:
package inventory3;
public class ItemDetails extends Items
{
public static void override()
{
private String Name;
private double pNumber, Units, Price;
public ItemDetails()
{
}
}
}
This is the Item class file that it is supposed to override:
package inventory3;
import java.lang.Comparable;
public class Items implements Comparable
{
private String Name;
private double pNumber, Units, Price;
public Items()
{
Name = "";
pNumber = 0.0;
Units = 0.0;
Price = 0.0;
}
public int compareTo(Object item)
{
Items tmp = (Items) item;
return this.getName().compareTo(tmp.getName());
}
public Items(String productName, double productNumber, double unitsInStock, double unitPrice)
{
Name = productName;
pNumber = productNumber;
Units = unitsInStock;
Price = unitPrice;
}
//setter methods
public void setName(String n)
{
Name = n;
}
public void setpNumber(double no)
{
pNumber = no;
}
public void setUnits(double u)
{
Units = u;
}
public void setPrice(double p)
{
Price = p;
}
//getter methods
public String getName()
{
return Name;
}
public double getpNumber()
{
return pNumber;
}
public double getUnits()
{
return Units;
}
public double getPrice()
{
return Price;
}
public double calculateTotalPrice()
{
return (Units * Price);
}
public static double getCombinedCost(Items[] item)
{
double combined = 0;
for(int i =0; i < item.length; ++i)
{
combined = combined + item[i].calculateTotalPrice();
}
return combined;
}
}
You simply declare a method with the same signature as the method in the parent class. So yours would look like:
package inventory3;
public class ItemDetails extends Items {
private String Name;
private double pNumber, Units, Price;
public ItemDetails(String Name, double pNumber, double Units, double Price) {
this.Name = Name;
this.pNumber = pNumber;
this.Units = Units;
this.Price = Price;
}
// getters and setters....
// The #Override is optional, but recommended.
#Override
public double calculateTotalPrice() {
return Units * Price * 1.05; // From my understanding this is what you want to do
}
}