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);
}
}
}
Related
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.
There is HashMap. I added all the product details in hashmap. I want to display the product details based on category. It means all same category products should be display. I am trying to create method for that. The method name is
public List<Product> getProductsBasedOnCategory(String category)
{
}
Please find below code.
Product.java
public class Product {
private long pid;
private String pname;
private String category;
private float price;
private long stock;
private String remarks;
public Product()
{
}
public Product(long pid,String pname,String category,float price,long stock,String remarks){
this.pid=pid;
this.pname=pname;
this.category=category;
this.price=price;
this.stock=stock;
this.remarks=remarks;
}
public long getPid() {
return pid;
}
public void setPid(long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public long getStock() {
return stock;
}
public void setStock(long stock) {
this.stock = stock;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
}
DatabaseClass.java
public class DatabaseClass {
private static Map<Long, Product> products=new HashMap<>();
public static Map<Long, Product> getProduct()
{
return products;
}
}
ProductDao.java
private Map<Long, Product> products=DatabaseClass.getProduct();
public ProductDaoImpl()
{
products.put(1L, new Product(1L,"TV","Entertinement",10000F,250L,"This is best TV!"));
products.put(2L, new Product(2L,"Computer","Technology",20000F,350L,"My Computer name Hp and SONY ViVo!"));
products.put(3L, new Product(3L,"DeskTopComputer","Technology",15000F,150L,"My Desktop Computer name Accer and SONY ViVo!"));
}
//Get All products
public List<Product> getAllProducts() {
return new ArrayList<Product>(products.values());
}
//Get product by product id
public Product getProduct(long pid) {
return products.get(pid);
}
//To Add the products
public Product addProduct(Product product) {
product.setPid(products.size()+1);
products.put(product.getPid(), product);
return product;
}
//Update the product
public Product updateProduct(Product product) {
if(product.getPid()<=0)
{
return null;
}
products.put(product.getPid(), product);
return product;
}
// Delete the product
public Product deleteProduct(long pid) {
return products.remove(pid);
}
//Get the product by category
public List<Product> getProductByCategory(String category) {
if(products.size()<=0)
{
return null;
}
else if(category.equals(products.get(Product))
{
}
I am trying a lot how to write code to get the value of model class in HashMap.
And how to write code for above getProductByCategory(String category).
You can iterate over the set of values in the map, and filter to return the list of matching products:
public List<Product> getProductByCategory(String category) {
if(products.size() == 0){
return new ArrayList<>();
}
return this.products.values().stream()
.filter(product -> product.getCategory().equals(category))
.collect(Collectors.toList());
}
You can also use a for-loop for that:
public List<Product> getProductByCategory(String category) {
List<Product> ret = new ArrayList<>();
if(products.size() == 0){
return ret;
}
for(Product p: this.products.values()) {
if(p.getCategory().equals(category))
ret.add(p);
}
return ret;
}
Please note that I return an empty ArrayList if the product map is empty. This is better practice for collection return types (instead of returning null)
One way is to iterate over the Hashmap as follows :
public List<Product> getProductsBasedOnCategory(String category)
{
List<Product> list = new ArrayList<Product>();
if (products.size()<=0) {
return list;
}
products.entrySet().stream().forEach((entry) -> {
if (((Product) entry.getValue()).getCategory().equals(category)) {
list.add(entry.getValue())
}
});
return list;
}
You have at least 2 options such as.
Have a specific map for each field you want to search by. This is
going to be faster if you have a lot of objects since searching in a
map takes O(1) while iterating through the entire collection takes
O(N). Big O Cheat Sheet
Declare the maps
private Map<Long, Product> productsByID = new HashMap();
private Map<String, Product> productsByCategory = new HashMap();
Initialize the maps
public ProductDaoImpl()
{
// Create the objects
Product p1 = new Product(1L,"TV","Entertinement",10000F,250L,"This is best TV!");
Product p2 = new Product(2L,"Computer","Technology",20000F,350L,"My Computer name Hp and SONY ViVo!");
Product p3 = new Product(3L,"DeskTopComputer","Technology",15000F,150L,"My Desktop Computer name Accer and SONY ViVo!");
//Assign the objects into the map by ids
productsByID.put(1L, p1);
productsByID.put(2L, p2);
productsByID.put(3L, p3);
//Assign the objects into the map by category
productsByCategory.put(p1.getCategory(), p1);
productsByCategory.put(p2.getCategory(), p2);
productsByCategory.put(p3.getCategory(), p3);
}
Use the same map you have and pretty
much iterate through all the values as the other answers explained.
Last,I don't know if this is just a exercise code and you have few values in which case the performance it doesn't matter that much or this is the beginning of your production code in which case you want to expect a lot of values.
If the latest is true, probably you want to model this into a DB (sql or not sql) and query by the specific field you want/need.
I am trying to learn oo design pattern and developing shopping cart application where different cart items will have different types. Each type is will have some additional attributes.
Option 1: Is it good to create a separate class with every cart item with their own attributes and common attributes in base class. In this option, I will have to create multiple classes and corresponding table hierarchy in the database.
Option 2: Create single cart item with type attribute which will identify the type of the attribute. Irrelevant attributes for the particular cart item will be null in this case.
I know this is very basic question but I want to know about how people follow best practices.
Thanks in advance.
I would use Strategy for this, for example:
public interface CartItem{
String getName();
BigDecimal getPrice();
}
Only work with this interface in your shopping cart. This way, if you want a new cart item, just let it implement this interface, and it will work :)
By using an interface, you still have full freedom in how you design your actual cart items (either having 1 class, or multiple classes)
It seems to me that you do NOT want to write new code when your application has to handle new things for people to buy. Therefore, a new class when there are new items to buy is a poor design.
I was asked a similar question in an interview. The exact requirement was
Design a shopping cart with products and coupons and calculate the net price after applying coupons on products. Coupons can be of different types with certain conditions. I tried to use abstraction among Coupon/Discount processing, Cart and Product implementations classes.
N% off that is 10% off for all the individual.
D% off on next item of Type T.
D% off on next item of Type T.
Sequentially apply all the coupons on the cart and get the Total amount.
I could come up with following solution. I used CoR pattern.
import java.util.ArrayList;
import java.util.List;
interface Cart {
List<CartItem> getItems();
// void setItems(Set<CartItem> cartItems);
}
class ShoppingCart implements Cart {
private List<CartItem> items = new ArrayList<>();
boolean addItem(CartItem item) {
return items.add(item);
}
boolean removeItem(CartItem item) {
items.remove(item);
return true;
}
public List<CartItem> getItems() {
return items;
}
public double totalCartValue() {
double total = 0;
for (CartItem item : items) {
total += item.getPrice();
}
return total;
}
}
interface CartItem {
public String getName();
public double getPrice();
public void setPrice(double price);
}
abstract class Product implements CartItem {
String name;
double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
class Card extends Product {
public Card(String name, double price) {
this.name = name;
this.price = price;
}
}
class Tshirt extends Product {
public Tshirt(String name, double price) {
this.name = name;
this.price = price;
}
}
class BackPack extends Product {
public BackPack(String name, double price) {
this.name = name;
this.price = price;
}
}
interface Coupon {
void apply(Cart cart);
void setSuccessor(Coupon successor);
}
class CouponAll implements Coupon {
private static final float DISCOUNT = 0.25f;
Coupon successor;
public void setSuccessor(Coupon successor) {
this.successor = successor;
}
public void apply(Cart cart) {
for (CartItem item : cart.getItems()) {
item.setPrice(item.getPrice() - item.getPrice() * DISCOUNT);
}
if (successor != null) {
successor.apply(cart);
}
}
}
class CouponNext implements Coupon {
private static final float DISCOUNT = 0.10f;
private int discountItemIndex;
Coupon successor;
CouponNext(int discountItemIndex) {
this.discountItemIndex = discountItemIndex;
}
public void setSuccessor(Coupon successor) {
this.successor = successor;
}
public void apply(Cart cart) {
if(discountItemIndex < cart.getItems().size()) {
CartItem cartItem = cart.getItems().get(discountItemIndex);
cartItem.setPrice(cartItem.getPrice() - cartItem.getPrice() * DISCOUNT);
}
if (successor != null) {
successor.apply(cart);
}
}
}
class CouponNextBackPack implements Coupon {
private static final float DISCOUNT = 0.15f;
private int discountItemStartIndex;
Coupon successor;
Class<?> productType;
CouponNextBackPack(int discountItemStartIndex ,Class<?> productType) {
this.discountItemStartIndex = discountItemStartIndex;
this.productType = productType;
}
public void setSuccessor(Coupon successor) {
this.successor = successor;
}
public void apply(Cart cart) {
if (discountItemStartIndex < cart.getItems().size()) {
for (int i = discountItemStartIndex; i < cart.getItems().size(); ++i) {
CartItem cartItem = cart.getItems().get(i);
if(productType.isInstance(cartItem)) {
cartItem.setPrice(cartItem.getPrice() - cartItem.getPrice() * DISCOUNT);
break;
}
}
}
if (successor != null) {
successor.apply(cart);
}
}
}
public class DriverClassCoR {
public static void main(String[] args) {
Product card1 = new Card("Card", 12.99);
Product card2 = new Card("Card", 12.99);
Product card3 = new Card("Card", 12.99);
Product tshirt1 = new Tshirt("Tshirt", 24.99);
Product tshirt2 = new Tshirt("Tshirt", 24.99);
Product backPack1 = new BackPack("BackPack", 34.99);
ShoppingCart cart = new ShoppingCart();
cart.addItem(card1); cart.addItem(card2); cart.addItem(card3);
Coupon couponAll = new CouponAll();
cart.addItem(tshirt1);
Coupon couponNext = new CouponNext(cart.getItems().size());
couponAll.setSuccessor(couponNext);
Coupon couponNextBackPack =null;
couponNextBackPack = new CouponNextBackPack(cart.getItems().size(), BackPack.class);
couponNext.setSuccessor(couponNextBackPack);
cart.addItem(tshirt2);
cart.addItem(backPack1);
System.out.println("Total car value before discounts \t" +cart.totalCartValue());
couponAll.apply(cart);
//System.out.println(backPack1.getClass().isInstance(backPack1));
System.out.println("Total car value after discounts \t" +cart.totalCartValue());
}
}
Hope this helps.
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 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);