Я пытался создать метод создания для добавления продуктов в ArrayList, проверяя, был ли он там. Но почему-то цикл не добавляет продукт в ArrayList, и я не могу понять, почему.
public class Shop1 {
private String shopName;
private ArrayList<Product> products;
private ArrayList<Customer> customers;
private ArrayList<Transaction> transactions;
public Shop1(String shopName)
{
this.shopName = shopName;
products = new ArrayList<Product>();
customers = new ArrayList<Customer>();
transactions = new ArrayList<Transaction>();
}
//addProduct
public void addProduct(String product_id,String product_name,int product_price,int product_amnt)
{
for(Product p:products)
{
if(p.getproduct_name().equals(product_name))
{
int amnt;
amnt = p.getproduct_stockamnt()+product_amnt;
p.setproduct_stockamnt(amnt);
}
else
{
Product pr = new Product(product_id,product_name,product_price,product_amnt);
products.add(pr);
}
}
}
4 ответа
Вы пытаетесь добавить продукт, просматривая products
. Так что, если products
пусто, ничего не произойдет.
Вы хотите полностью просмотреть продукты, а затем, возможно, добавить их.
Примерно так:
public void addProduct(String product_id, String product_name, int product_price, int product_amnt)
{
for (Product p: products)
{
if (p.getproduct_name().equals(product_name))
{
int amnt = p.getproduct_stockamnt() + product_amnt;
p.setproduct_stockamnt(amnt);
return; // found so no need to go any further
}
}
// We did not find it, so add a new product:
Product pr = new Product(product_id,product_name,product_price,product_amnt);
products.add(pr);
}
Есть одна основная проблема с методом addProduct () .
Использование цикла for-each - это метод итерации, при котором вы создаете новую временную переменную, в которой сохраняете текущий элемент, имеющий указатель. На каждой итерации указатель увеличивается (увеличивается на 1), поэтому на каждой итерации во временной переменной будет новый элемент. Поэтому в вашем коде в строке
amnt = p.getproduct_stockamnt()+product_amnt;
p.setproduct_stockamnt(amnt);
В конечном итоге вы устанавливаете запас временной переменной p на amnt . Следующая итерация, через которую пройдет цикл, сотрет последний результат, и, следовательно, ваши изменения не будут видны.
Использование цикла for-index позволит изменить фактический список ArrayList, а не временную переменную.
Использование цикла for-index
for(int i = 0;i<products.size();i++)
{
Product currentProduct = products.get(i);
//similar to the for-each loop as there is a temporary variable
if(currentProduct.getproduct_name().equals(product_name))
{
int amnt = currentProduct.getproduct_stockamt()+product_amnt;
//however stock is being added to the original location in the list
products.get(i).setproduct_stockamnt(amnt);
}
else
{
Product pr = new Product(product_id,product_name,product_price,product_amnt);
products.add(pr);
}
}
Магазин:
package stackoverflow.weirdshop;
import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.TreeMap;
public class Shop1 {
private final TreeMap<Product, Long> products2amount = new TreeMap<>();
private final ArrayList<Customer> customers = new ArrayList<>();
private final ArrayList<Transaction> transactions = new ArrayList<>();
public final String shopName;
public Shop1(final String pShopName) {
this.shopName = pShopName;
}
public void changeStock(final Product pProduct, final int pAmount) {
synchronized (products2amount) {
final Long oldAmount = products2amount.get(pProduct); // you might also do some checks of how many you can remove with negative pAmount
final long newAmount = (oldAmount == null) ? (pAmount) : (oldAmount.longValue() + pAmount);
products2amount.put(pProduct, Long.valueOf(newAmount));
}
}
public void printContent() {
System.out.println("Contents of " + shopName + ":");
for (final Entry<Product, Long> e : products2amount.entrySet()) {
System.out.println("\t" + e.getKey() + "\tAmount: " + e.getValue());
}
}
}
Продукт:
package stackoverflow.weirdshop;
public class Product implements Comparable<Product> {
public final String mID;
public final String mName;
public final int mPrice;
public Product(final String pID, final String pName, final int pPrice) {
mID = pID;
mName = pName;
mPrice = pPrice;
}
public String getName() {
return mName;
}
@Override public String toString() {
return "Product [mID=" + mID + "\n\t\tmName=" + mName + "\n\t\tmPrice=" + mPrice + "]";
}
@Override public int compareTo(final Product pOther) {
return mName.compareTo(pOther.mName); // sort only by name
}
}
Простой пример:
package stackoverflow.weirdshop;
public class TestShop {
public static void main(final String[] args) {
final Product bier = new Product("0815", "Bier", 2);
final Product schnaps = new Product("0123", "Schnaps", 8);
final Product wein = new Product("9876", "Wein", 5);
final Shop1 shop = new Shop1("Dings");
shop.changeStock(bier, 20);
shop.printContent();
shop.changeStock(schnaps, 8);
shop.changeStock(wein, 4);
shop.printContent();
shop.changeStock(bier, 13);
shop.printContent();
}
}
Выход:
Contents of Dings:
Product [mID=0815
mName=Bier
mPrice=2] Amount: 20
Contents of Dings:
Product [mID=0815
mName=Bier
mPrice=2] Amount: 20
Product [mID=0123
mName=Schnaps
mPrice=8] Amount: 8
Product [mID=9876
mName=Wein
mPrice=5] Amount: 4
Contents of Dings:
Product [mID=0815
mName=Bier
mPrice=2] Amount: 33
Product [mID=0123
mName=Schnaps
mPrice=8] Amount: 8
Product [mID=9876
mName=Wein
mPrice=5] Amount: 4
Не знаю точной причины, но попробуйте индексированный подход.
Используйте индексы с циклом for, а не с Product p.
Не уверен, но такие вещи в основном происходят из-за проблем, связанных с областью применения.
Возьмем, к примеру, этот фрагмент:
int a = 3;
{
int a = 5;
}
System.out.println(a); // Results in 3
Такие проблемы в основном возникают, если область видимости является локальной, поэтому, когда она выходит из цикла, она сбрасывается до исходного состояния.
Итак, попробуйте что-то с индексом с использованием размера, который даст вам ожидаемый результат, поскольку переменная int будет уничтожена после области видимости, но изменение будет сделано там, где это ожидается.
Похожие вопросы
Новые вопросы
java
Java - это язык программирования высокого уровня. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег редко используется отдельно и чаще всего используется вместе с [spring], [spring-boot], [jakarta-ee], [android], [javafx], [hadoop], [gradle] и [maven].