简体   繁体   中英

My program is printing only the last input from the ArrayList

I have another small class containing the main method that display the
invoice, but the toString method here is only displaying the last item entered, not the three itemnames,quantities, prices and totalPrice. I have doubts about addItemLine and toString . Can someone see what I am missing here? I was enable to past the lineItem class code.

import java.util.ArrayList;
import java.util.Scanner;


public class Transaction {
     private ArrayList<lineItem> lineItems;
     private int customerID;
     private String customerName; 


public Transaction (int customerID, String customerName){
      this.customerID= customerID;
      this.customerName= customerName;
      this.lineItems= new ArrayList<>();
}
    public int getcustomerID(){
        return customerID;
}
    public void setcustomerID(int customerID){
        this.customerID = customerID;
}

    public String getcustomerName(){
        return customerName;
}
    public void setcustomerName(String customerName){
        this.customerName = customerName;
}
    public ArrayList addItemLine(lineItem line){

          Scanner mykey=new Scanner(System.in);
          for (int i=0; i<2;i++){
          String k= line.getItemName();
          int m= line.getQuantity();
          double d= line.getPrice();   

          System.out.println("enter item name:");
          k = mykey.next();
          line.setItemName(k);
          System.out.println("enter quantity:");
          m= mykey.nextInt();
          line.setQuantity(m);
          System.out.println("enter unit price:");
          d= mykey.nextDouble();
          line.setPrice(d);
          line.getItemName(); line.getQuantity(); line.getPrice();
          lineItems.add(new lineItem(k,m,d));
    }
          return this.lineItems;
   }
       public void updateItem(String item, int quant, double pri){
           lineItem l= new lineItem(item, quant, pri);
           int m=0;
           m= l.getQuantity();
           m=m+quant;
           double tot=0;    
   }
   public double getTotalPrice(){
         double totalPrice = 0;

         for (int i =0;i<2; i++){
              lineItem item = lineItems.get(i);
              totalPrice = totalPrice + item.getTotalPrice();
          }
             return totalPrice;

}
public String getLineItem( String s, int d, double k){
      lineItem o= new lineItem(s,d,k);
      for (int i =0;i<2; i++){
      if (!s.equals(o.getItemName()))
      System.out.println("item not found");
      else
         s= (o.getItemName() + o.getQuantity() + o.getPrice());
}
     return s;
}
public String toString(lineItem lin) {
      String a="", b="";

      a=("Customer ID:" + this.getcustomerID() + "\n" + "Customer Name: " +   
      this.getcustomerName());
      for (int i=0; i<2;i++){
      b= ("\n\n" + lin.getItemName() + "\t" + "Qty" + lin.getQuantity() + "   
      "   
      + "@" + lin.getPrice() + "  "+ "\t" + "$" + lin.getTotalPrice());  
  }
      return a + b;
}

TransactionTesting:

    import java.util.Scanner;


   public class TransactionTesting {


          public static void main(String args[]) {
                String m=""; int g=0; double r=0; int id=0; String name="";

                Scanner mykey= new Scanner(System.in);
                System.out.println("enter customer name:");
                name= mykey.nextLine();
                System.out.println("enter customer ID:");


        id=mykey.nextInt();
            Transaction mytrans= new Transaction(id, name);
            lineItem line= new lineItem(m,g,r);
            mytrans.addItemLine(line);

            System.out.println(mytrans.toString(line));
         }
       }

Change your toString() method like this:

public String toString() {
        String a="", b="";

        a=("Customer ID:" + this.getcustomerID() + "\n" + "Customer Name: " +   
                this.getcustomerName());
        for (lineItem item : this.lineItems)
            b += ("\n\n" + item.getItemName() + "\t" + "Qty" + item.getQuantity() + "   "   
                    + "@" + item.getPrice() + "  "+ "\t" + "$" + item.getPrice());  

        return a + b;
    }

and from your test class call this method as the following:

System.out.println(mytrans.toString());

You don't need any argument in order to print your entire list. Try to refactor your code a bit. It works, but it can be written better and better ;)

1) The call

System.out.println(mytrans.toString(line));

is printing out the single lineitem that is passed to it. What you probably intended was for Transaction.toString() to iterate over its list Transaction.lineItems and print each item in turn.

In fact Transaction.toString() doesn't need to take in a lineItem argument, the method should merely print out the internals of the class instance.

2) There is a similar confusion in Transacton.addItemLine() . It accepts a lineItem, prompts the user for new values, updates lineItem.. then constructs a new lineItem to store in Transaction.lineItems . It isn't actually causing a bug that I can see but you should get rid of the lineItem argument entirely; addItemLine doesn't need it.

3) Incidentally:

for (int i=0; i<2;i++){ }

loops twice, not three times. I trust you would have caught that in testing.

4) There is also a line of code near the end of addItemLine that doesn't actually do anything! Maybe you can spot that one on your own.

There are some other issues but those are the ones that leapt out at me.

Simply put, in your method "addItemLine" you take data from 1 lineItem, overwrite it with some keyboard input, and the put in the list 2 other lineItem instances. Then in the test code you print the original lineItem, which is not even in the list.

The method itself iterates on nothing, just creates twice the same string "b". I suggest you to look at some tutorials on arrays and for loops.

Just a quick non-tested solution that may work. Something is copied from your code, something is changed because your code was wrong.

// If you create this inside the method than you'll lose everything everytime you call addItemLine
private ArrayList<lineItem> lineItems;

public void addItemLine(lineItem line){
      Scanner mykey=new Scanner(System.in);
      for (int i=0; i<2;i++){
      String k= line.getItemName();
      int m= line.getQuantity();
      double d= line.getPrice();   

      System.out.println("enter item name:");
      k = mykey.next();
      line.setItemName(k);
      System.out.println("enter quantity:");
      m= mykey.nextInt();
      line.setQuantity(m);
      System.out.println("enter unit price:");
      d= mykey.nextDouble();
      line.setPrice(d);
      line.getItemName(); line.getQuantity(); line.getPrice();
      lineItems.add(new lineItem(k,m,d));
      // This doesn't have to return anything, it just adds to the list
}

// No parameteres, this should build the string for the current object
public String toString() {
    // String concatenation is not the best idea, StringBuilder is better
    StringBuilder sb = new StringBuilder();
    // If you want to print all of them then you need to iterate over the list
    for (lineItem item : lineItems){
        sb.append("Customer ID:" + this.getcustomerID() + "\n" + "Customer Name: " + this.getcustomerName());
        for (int i=0; i<2;i++){
            // Copied from your code
            sb.append("\n\n" + lin.getItemName() + "\t" + "Qty" + lin.getQuantity() + " "+ "@" + lin.getPrice() + "  "+ "\t" + "$" + lin.getTotalPrice());  
        }
    sb.append("\n);
    }
    return sb.toString();
}

It seems that you don't understand how to create a Java object, or how to keep your application model separate from your application view.

Here's a test run of your code, after I made some changes.

Enter customer name: Gilbert
Enter customer ID: 123
Enter item name: Spinach
Enter quantity: 5
Enter unit price: .89

Customer ID:   123
Customer Name: Gilbert

Spinach Qty 5         @0.89     $4.45

Enter item name: Corn
Enter quantity: 12
Enter unit price: .29

Customer ID:   123
Customer Name: Gilbert

Corn    Qty 12         @0.29    $3.4799999999999995

Enter item name: 

First, let's look at your Java objects. The first Java object which you didn't include, is LineItem. Note that Java class names start with a capital letter.

package com.ggl.transaction;

public class LineItem {
    private String itemName;
    private int quantity;
    private double price;

    public LineItem(String itemName, int quantity, double price) {
        this.itemName = itemName;
        this.quantity = quantity;
        this.price = price;
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getTotalPrice() {
        return price * quantity;
    }

}

A Java object consists of class fields, and getters and setters for the fields.

Next, here's your Transaction class.

package com.ggl.transaction;

import java.util.ArrayList;
import java.util.List;

public class Transaction {
    private List<LineItem> lineItems;
    private int customerID;
    private String customerName;

    public Transaction(int customerID, String customerName) {
        this.customerID = customerID;
        this.customerName = customerName;
        this.lineItems = new ArrayList<>();
    }

    public int getcustomerID() {
        return customerID;
    }

    public void setcustomerID(int customerID) {
        this.customerID = customerID;
    }

    public String getcustomerName() {
        return customerName;
    }

    public void setcustomerName(String customerName) {
        this.customerName = customerName;
    }

    public void addItemLine(LineItem line) {
        this.lineItems.add(line);
    }

    public void updateItem(String item, int quant, double pri) {
        LineItem l = new LineItem(item, quant, pri);
        int m = 0;
        m = l.getQuantity();
        m = m + quant;
        l.setQuantity(m);
    }

    public double getTotalPrice() {
        double totalPrice = 0;

        for (int i = 0; i < 2; i++) {
            LineItem item = lineItems.get(i);
            totalPrice = totalPrice + item.getTotalPrice();
        }
        return totalPrice;

    }

    public String getLineItem(String s, int d, double k) {
        LineItem o = new LineItem(s, d, k);
        for (int i = 0; i < 2; i++) {
            if (!s.equals(o.getItemName()))
                System.out.println("item not found");
            else
                s = (o.getItemName() + o.getQuantity() + o.getPrice());
        }
        return s;
    }

    public String toItemString(LineItem lin) {
        String b = "";

        String a = ("Customer ID:   " + this.getcustomerID() + "\n"
                + "Customer Name: " + this.getcustomerName());
        for (int i = 0; i < 2; i++) {
            b = ("\n\n" + lin.getItemName() + "\t" + "Qty " + lin.getQuantity()
                    + "         " + "@" + lin.getPrice() + "  " + "\t" + "$"
                    + lin.getTotalPrice() + "\n");
        }
        return a + b;
    }

}

I simplified your addItemLine class. Code that receives input using the Scanner class belongs in your TransactionTesting class.

I renamed your toString method to toItemString. toString is a method of the Object class. Since your method has a parameter, I renamed it to lessen any confusion.

Finally, here's your TransactionTesting class. I fixed it up so it would work. You can specify any number of line items. To stop processing, just enter a blank item name.

package com.ggl.transaction;

import java.util.Scanner;

public class TransactionTesting {

    public static void main(String args[]) {
        Scanner mykey = new Scanner(System.in);
        System.out.print("Enter customer name: ");
        String name = mykey.nextLine().trim();
        System.out.print("Enter customer ID: ");
        int id = Integer.valueOf(mykey.nextLine().trim());

        Transaction mytrans = new Transaction(id, name);
        boolean processing = true;
        while (processing) {
            System.out.print("Enter item name: ");
            String k = mykey.nextLine().trim();
            if (k.equals("")) {
                processing = false;
            } else {
                System.out.print("Enter quantity: ");
                int m = Integer.valueOf(mykey.nextLine().trim());
                System.out.print("Enter unit price: ");
                double d = Double.valueOf(mykey.nextLine().trim());

                LineItem lineItem = new LineItem(k, m, d);
                mytrans.addItemLine(lineItem);
                System.out.println("\n" + mytrans.toItemString(lineItem));
            }
        }

        mykey.close();
    }
}

Remember, keep your application model (LineItem & Transaction) separate from your application view (TransactionTesting).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM