2016-09-07 2 views
2

У меня есть абстрактный класс Transaction, где бы я хотел был бы рассчитать общую стоимость каждого Transaction. Общая стоимость рассчитывается путем получения цены каждого Product в Map, а затем умножить эту цену на количество каждого Product. Я просто не знаю, как умножить эти цены на величины, которые являются значениями в Map. Кто-нибудь может мне помочь? Я пробовал почти все, и ничего не работает.Расчетная стоимость

public abstract class Transaction 
{ 
    //Attributes 
    ... 

    //Links 

    Map<Product,Integer> products; 

    //Constructor 

    Transaction() 
    { 
     id = newTrId.incrementAndGet(); 
     date = new Date(); 
     products = new HashMap<>(); 
    } 

    abstract void addProduct(Product aProduct, int aQuantity); 


    BigDecimal calculateTotal() 
    { 
     BigDecimal total = new BigDecimal(0); 

     for(Product eachProduct : products.keySet()) 
     { 
      total.add(eachProduct.getPrice()); 
     } 
     for (Integer eachProduct : products.values()) 
     { 

     } 

     return total; 
    } 
} 
+1

'total.add (eachProduct.getPrice() * products.get (eachProduct));' Это будет захватить 'Integer' в' '' продуктов Карта 'и умножить на цену' eachProduct'. Добавьте это в свой цикл 'for-each' вместо того, чтобы делать другой цикл. – Orin

ответ

0

Я просто не знаю, как умножить эти цены на величины, которые в виде значений в Map. Кто-нибудь может мне помочь?

Это может быть сделано перебором записей вашего Map для того, чтобы умножить количество (значение Map) по своей цене, как это:

BigDecimal calculateTotal() { 
    BigDecimal total = new BigDecimal(0); 
    for (Map.Entry<Product, Integer> entry : products.entrySet()) { 
     total = total.add(
      BigDecimal.valueOf(entry.getKey().getPrice()).multiply(
       BigDecimal.valueOf(entry.getValue()) 
      ) 
     ); 
    } 
    return total; 
} 

NB: Я предположим, что Product#getPrice() возвращает double.

NB 2 Как BigDecimal является непреложный, вам нужно повторно назначить переменную total на каждой итерации.

NB 3 Чтобы избежать потери точности при вычислении, необходимо преобразовать все в BigDecimal.

0

Вы были близки. Вот посмотрите:

BigDecimal calculateTotal() 
{ 
    BigDecimal total = new BigDecimal(0); 

    for(Product eachProduct : products.keySet()) 
    { 
     total.add(eachProduct.getPrice() * products.get(eachProduct)); 
    } 

    return total; 
} 

Единственная разница эта линия: total.add(eachProduct.getPrice() * products.get(eachProduct));

Я добавил это, чтобы захватить Integer с карты, связанной с Product.

Если вы используете Java 8, вы также можете создать поток.

total = new BigDecimal(map.keySet() 
    .stream().mapToDouble(product -> product.getPrice() * products.get(product)) 
    .sum()); 
+0

Спасибо, но NetBeans говорит, что double не может быть преобразован в BigDecimal, когда я это делаю. – Joanna

+0

Хммм, это сработало, когда я его протестировал. Вы используете Java 8? – Orin

1

BigDecimal неизменен и add не изменяет объект, для которого он вызывается. Так что вам нужно переназначить результат add:

BigDecimal calculateTotal() { 
    BigDecimal total = new BigDecimal(0); 
    for (Map.Entry<Product, Integer> entry : products.entrySet()) { 
    total = total.add(BigDecimal.valueOf(entry.getKey().getPrice() * entry.getValue())); 
    } 
    return total; 
} 
Смежные вопросы