如何在当前货运场景中使用对象数组?并计算含20条货运记录的数组中本地货运的总费用
Hey there! Let's work through the issues in your code step by step so you can correctly calculate the total cost of local shipments. I've spotted a few key problems that are keeping your code from working as expected.
Key Issues in Your Current Code
Uninitialized Shipment Array: You created
Shipment[] a = new Shipment[20];but never put any actual Shipment objects into it. Right now, every element in that array isnull, so when you try to calla[i].isLocalShipment(), you'll hit aNullPointerExceptionimmediately.Incorrect String Comparison: In both
isLocalShipment()andcalcCost(), you're using==to compare city names. In Java,==checks if two String variables point to the exact same object in memory—not if their text content is the same. For content comparison, you need to useequals()(orequalsIgnoreCase()if you want to ignore case differences like "dubai" vs "Dubai").Not Accumulating the Total Cost: Your code prints the cost of individual local shipments, but it never adds those values to your
localvariable. That means you'll never get the total sum you're trying to calculate.Broken
setFromAddressMethod: The logic here is reversed—you're taking the existing city/phone values fromfromAddressand assigning them to the method parameters, instead of updatingfromAddresswith the new values passed into the method.
Corrected Code
First, let's fix the core Shipment class:
public class Shipment { public Parcel item; private Address fromAddress; private Address toAddress; public String senderName; public Shipment(Parcel i, Address f, Address t, String name) { item = i; fromAddress = f; toAddress = t; senderName = name; } // Fixed setter: now updates fromAddress with the new values passed in public void setFromAddress(String c, String p) { fromAddress.setCity(c); fromAddress.setPhone(p); } public boolean isLocalShipment() { // Use equals() to compare the actual text of the city names return fromAddress.getCity().equals(toAddress.getCity()); } public double calcCost() { double cost = 0; // Again, use equals() for city comparison if (fromAddress.getCity().equals(toAddress.getCity())) { cost = 5; } else { cost = 15; } // Use else if for cleaner, non-redundant weight checks if(item.weight > 0 && item.weight <= 200) { cost += 5.5; } else if(item.weight > 200) { cost += 10.5; } // Apply 50% tax (your original calculation was correct here!) return cost * 1.5; } public String toString() { return "From: " + senderName + "\nTo: " + toAddress + "\nParcel: " + item.desc + " " + item.weight + "\ncost: " + calcCost(); } }
Next, let's fix the TestShipment class. I've added code to populate your 20-element array with sample shipments (you can replace this with your actual 20 records):
package question; public class TestShipment { public static void main(String[] args) { // Sample shipment to test initially Shipment r1 = new Shipment( new Parcel("scientific calculator", 250), new Address("Dubai","05512345678"), new Address("Dubai","0505432123"), "Salim" ); System.out.println(r1); // Initialize and populate the 20-element Shipment array Shipment[] a = new Shipment[20]; for (int i = 0; i < a.length; i++) { // Alternate between local and international shipments for testing String fromCity = (i % 2 == 0) ? "Dubai" : "Abu Dhabi"; String toCity = (i % 2 == 0) ? "Dubai" : "Sharjah"; a[i] = new Shipment( new Parcel("Item " + (i+1), 150 + (i*10)), new Address(fromCity, "055" + (1234567 + i)), new Address(toCity, "050" + (7654321 + i)), "Sender " + (i+1) ); } double totalLocalCost = 0; for (int i = 0; i < a.length; i++) { Shipment shipment = a[i]; if (shipment.isLocalShipment()) { double cost = shipment.calcCost(); System.out.println("Local Shipment " + (i+1) + " Cost: " + cost); // Add this shipment's cost to the total totalLocalCost += cost; } } // Print the final total you care about! System.out.println("\nTotal Cost of All Local Shipments: " + totalLocalCost); } }
You'll also need to make sure your Address class has proper getter and setter methods (since we use them in the fixed setFromAddress):
public class Address { private String city; private String phone; public Address(String city, String phone) { this.city = city; this.phone = phone; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return city + " (" + phone + ")"; } }
And finally, the Parcel class (since it's referenced in your code):
public class Parcel { public String desc; public double weight; public Parcel(String desc, double weight) { this.desc = desc; this.weight = weight; } }
What Changed & Why
- Array Population: We now fill the 20-element array with actual Shipment objects to avoid
NullPointerException. Swap out the sample generation code with your real 20 records. - String Comparison: Using
equals()ensures we correctly identify local shipments by matching city name content, not just object references. - Total Cost Accumulation: The
totalLocalCost += cost;line adds each local shipment's cost to the running total, so you get the final sum you need. - Fixed Setter: The
setFromAddressmethod now properly updates the origin address with the values you pass in. - Cleaner Weight Logic: Using
else ifincalcCost()means we don't waste time checking if weight is >200 when we already know it's <=200.
内容的提问来源于stack exchange,提问作者O H

