我确定java arraylist总和必须有一个更简单的方法

时间:2014-02-19 11:20:44

标签: java arraylist multiplying

我刚开始用Java开始我的第一个真正的项目,所以我仍然理解基础知识,为此道歉。

我正在计算价格*数量然后给每个产品的总金额,然后必须在订单处理过程中对我的所有产品重复这一过程。所以我想找到最好的方式让我重复一遍。

这是我的工作代码:

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

   double priceA = 20.00;/*fixed price*/
   String strA = txtbxCaseA.getText();/*gets amount from textbox*/
   int numA = Integer.parseInt(strA);/*parse to int */
   double casetotalA = (priceA * numA);/*sum*/
   String caseAtotal = String.valueOf(casetotalA);/*to string */

   double priceB = 25.00;
   String strB = txtbxCaseB.getText();
   int numB= Integer.parseInt(strB);
   double casetotalB = (priceB * numB);
   String caseBtotal = String.valueOf(casetotalB);

   double priceC = 30.00;
   String strC = txtbxCaseC.getText();
   int numC = Integer.parseInt(strC);
   double casetotalC = (priceC * numC);
   String caseCtotal = String.valueOf(casetotalC);

    ArrayList caselist = new ArrayList();
    caselist.add("Case A Total - £" + caseAtotal);
    caselist.add("Case B Total - £" + caseBtotal);
    caselist.add("Case C Total - £" + caseCtotal);

    DefaultListModel myModel = new DefaultListModel ();

    for(int i = 0; i < caselist.size(); i++){
        jTextArea3.append((String)caselist.get(i) + ('\n'));
        myModel.addElement(caselist.get(i) + ",");

        /*
        - save arraylist to a gobal varible for cart processing
        - move to next panel (page) along
        */
    }
}                                        

我的问题是,这种方法是不错的做法,也是他们更好的方法(可能更短),我可以为我的50种产品中的每一种重复,因为这似乎有点低效但是有效。

非常感谢任何建议或意见。

5 个答案:

答案 0 :(得分:2)

  

是他们更好的方法(可能更短),我可以重复每一个   我的50个产品

为什么不将您的产品存储在一个集合(List)中,以便您可以随时遍历每个产品和总计?如果你有一个Product对象,那么你可以为每个成员分配一个价格,并在你去的时候迭代总计。

for (Product p : listOfProducts) {
   sum = sum + p.price * quantity;
}

请注意,我会将上述内容放入价格计算器或类似计算器中,以便您可以与GUI Swing代码分开运行和测试(通过单元测试框架,如JUnit)。

答案 1 :(得分:1)

可以做的一件事是你可以使用TextBox数组并创建一个计算值并在Arraylist中插入的函数,并在按钮事件处理程序方法内的循环中调用此函数。另请尝试使用ArrayList<String>代替ArrayList。这确保了更强的类型检查。

答案 2 :(得分:0)

自您提及以来最佳做法的一些提示:

double priceA = 20.00;

首先double并不完全准确,您应该注意是否计划使用浮点变量进行必须100%准确的任何计算(例如资金计算),使用{{ 1}}类而不是。

其次,您应该将所有常量(固定)值存储在您定义变量的类的顶部,这样您就不会漫游任何“幻数”。

示例:java.math.BigDecimal

这样,每次访问该方法时都不必重新定义变量。

第三,你应该始终怀疑用户输入并处理它。

如果我将其中一个文本框留空,那么private static final double priceA = 20.00会发生什么?

或者更糟糕的是,如果我在那里写一些文字而不是数字呢?

您应该始终注意,用户不会总是按预期使用您的程序,甚至会尝试破解它。

最后,您可以在此方法之外定义一种计算方法,以简化您当前的方法。

从您的示例中可能看起来像这样:

Integer.parseInt(strA)

这会将原始方法缩减为:

private String calculcateTotal(double price, String amount) {
    int actualAmount = Integer.parseInt(amount);
    double totalAmount = (price * actualAmount);
    return String.valueOf(totalAmount);
}

看看它现在看起来怎么样?

你甚至可以省略

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

   double priceA = 20.00;
   double priceB = 25.00;
   double priceC = 30.00;

    ArrayList caselist = new ArrayList();
    caselist.add("Case A Total - £" + calculateTotal(priceA, txtbxCaseA.getText()));
    caselist.add("Case B Total - £" + calculateTotal(priceB, txtbxCaseB.getText()));
    caselist.add("Case C Total - £" + calculateTotal(priceC, txtbxCaseC.getText()));

    DefaultListModel myModel = new DefaultListModel ();

    for(int i = 0; i < caselist.size(); i++){
        jTextArea3.append((String)caselist.get(i) + ('\n'));
        myModel.addElement(caselist.get(i) + ",");

        /*
        - save arraylist to a gobal varible for cart processing
        - move to next panel (page) along
        */
    }
}

如果你像我之前提到的那样在你的班级顶层定义了它们。

答案 3 :(得分:0)

我的建议是将业务逻辑与表示逻辑分开,你最终会得到这样的结果:

/**
 * Represents the concept of getting a `Integer` quantity from some source.
 */
public inteface Quantity
{
  public Integer getValue();
}

/**
 * Represents the combination of a price and quantity to produce a total.
 */    
public class Total
{
  private double price;
  private Quantity quantity;

  public Total(double price, Quantity quantity)
  {
    this.price = price;
    this.quantity = quantity;
  }

  public Double getValue()
  {
    Integer quantity = quantity.getValue();
    return quantity != null ? quantity * price : null; 
  }
}

然后你可以在你的Swing代码中使用这个inteface和class(这只是为了显示与Swing的交互,而不是如何布局控件):

public class MyFrame extends JFrame
{
  private static final List<Double> PRICES = Arrays.asList(20.0, 25.0, 30.0);      

  public MyFrame()
  {
    List<Total> totals = new ArrayList<Total>();

    JList totalsList = new JList(new TotalListModel(totals));
    addComponent(totalsList);

    for (Double price : PRICES)
    {
      JTextField quantityTextField = new JTextField();
      quantityTextField.addActionListener(new RepaintComponentActionListener(totalsList));
      addComponent(quantityTextField);

      totals.add(new Total(price, new TextFieldQuantity(quantityTextField)));
    }
  }

  private class TotalListModel extends AbstractListModel
  {
    private List<Total> totals;

    public TotalListModel(List<Total> totals)
    {
      this.totals = totals;  
    }

    public Object getElementAt(int index) 
    {
      Double value = totals.get(index).getValue();
      return value != null ? value.toString() : "NO VALUE";
    }

    public int getSize() 
    {
      return totals.size();
    }
  }

  private class TextFieldQuantity implements Quantity
  {
    private JTextField textField;

    public TextFieldQuantitySource(JTextField textField)
    {
      this.textField = textField;
    }

    public Integer getQuantity()
    {
      try
      {
        return Integer.parseInt(textField.getText()); 
      }
      catch (NumberFormatException e)
      {
        return null; 
      } 
    }
  }

  private class RepaintComponentActionListener implements ActionListener
  {
    private Component component;

    public RefreshControlActionListener(Component component)
    {
      this.component = component;
    }

    public void actionPerformed(ActionEvent actionEvent) 
    {
      component.repaint();
    }
  }
}    

如果不能立即清楚此代码是如何工作的,则使用:

  • 自定义ListModel以包裹totals,意味着JList只需要重新绘制,并且将显示当前总计。
  • PRICES上方循环以动态创建JTextField控件(我会让它为您设计布局)。
  • 自定义ActionListener,当任何JList更改时,会重新显示JTextField
  • 自定义Quantity,用于读取JTextField
  • 中的值

答案 4 :(得分:0)

改善整体项目的一些提示,让您更轻松。其中一些提示已经在其他答案中公布。

基本原则是(就像Ceiling Gecko评论的那样):如果你看到自己重复代码,那就用一种通用的方式对代码进行一次编码,并为每次重复重用代码。

使用产品类

public class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}

您将在程序一开始就填写所有产品,并将其存储在arrayList

List<Product> productList = new ArrayList<Product>();
productList.add(new Product("Milk", 10.00));
productList.add(new Product("Bread", 20.00));

此处的产品是硬编码的,但您可能希望从文件或数据库中读取它。稍后会详细介绍。

Collections

使用泛型

Why Use Generics?

动态生成'TextBoxes'

如果为了输入金额而为JPanel编码50 JTextField s,那么当您添加其他产品时会发生什么?
然后您必须更改代码。

如果您使用之前提到的List Product,则可以动态生成JTextField个 如果您从文件或数据库中填充列表,则在更新产品列表和/或价格时,您将永远不必更改代码。然后,您只需更新您的文件或数据库,更改将反映在您的代码中。

List<JTextField> textFields = new ArrayList<JTextField>();
for (Product p : productList) {
    textFields.add(new JTextField());
}

然后将该列表与产品列表一起使用,将Component放在JPanel

JPanel panel = new JPanel();
for (int i = 0; i < textFields.size(); i++) {
    panel.add(new JLabel(productList.get(i).getName()));
    panel.add(textFields.get(i));
}

将您的计算代码放在一个单独的可重用方法

private double calculateTotal(String amount, double cost) {
    int amnt = Integer.parseInt(amount);
    return cost * amnt;
}

现在循环生成的'TextBoxes'来计算总数

处理Integer.parseInt

可能抛出的NumberFormatException
private void jButton2ActionPerformed(ActionEvent evt) {
    caselist = new ArrayList<String>();
    for (int i = 0; i < textFields.size(); i++) {
        try {
            double total = calculateTotal(textFields.get(i).getText(), productList.get(i).getPrice());
            caselist.add(productList.get(i).getName() +" Total - £" +  total);
        } catch (NumberFormatException e) {
            caselist.add(productList.get(i).getName() +" invalid amount");
        }
    }
}

以下所有内容都归为一个

所以你可以复制并运行它以查看它们是如何组合在一起的 它被快速组合在一起,因此它不是构建程序的最佳方式

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ProductCalc extends JFrame {
    public static void main(String[] args) {
        new ProductCalc();
    }

    private List<Product> productList;
    private List<JTextField> textFields;
    private List<String> caselist;

    public ProductCalc() {
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        productList = new ArrayList<Product>();
        productList.add(new Product("Milk", 10.00));
        productList.add(new Product("Bread", 20.00));
        productList.add(new Product("Eggs", 5.00));

        textFields = new ArrayList<JTextField>();
        for (Product p : productList) {
            textFields.add(new JTextField(10));
        }

        JPanel panel = new JPanel();
        for (int i = 0; i < textFields.size(); i++) {
            panel.add(new JLabel(productList.get(i).getName()));
            panel.add(textFields.get(i));
        }

        JButton button = new JButton("click");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });
        panel.add(button);

        this.setSize(500, 500);
        this.add(panel);
        this.setVisible(true);
    }

    private void jButton2ActionPerformed(ActionEvent evt) {
        caselist = new ArrayList<String>();
        for (int i = 0; i < textFields.size(); i++) {
            try {
                double total = calculateTotal(textFields.get(i).getText(), productList.get(i).getPrice());
                caselist.add(productList.get(i).getName() + " Total - £" + total);
            } catch (NumberFormatException e) {
                caselist.add(productList.get(i).getName() + " invalid amount");
            }
        }
        for (String s : caselist) {
            System.out.println(s);
        }
    }

    private double calculateTotal(String amount, double cost) {
        int amnt = Integer.parseInt(amount);
        return cost * amnt;
    }
}

class Product {
    private String name;
    private double price;

    public Product(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public double getPrice() {
        return price;
    }
}