【问题标题】:Trying to take 2 arrayLists and multiply them and store the new values into a new arrayList to find the min/max尝试获取 2 个数组列表并将它们相乘并将新值存储到新的数组列表中以找到最小值/最大值
【发布时间】:2015-03-19 07:24:20
【问题描述】:

我的代码不工作,我不知道为什么。这是我收到的错误:

Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:350)
at java.util.Collections.max(Collections.java:638)
at Project01.getHighestDollarAmount(Project01.java:120)
at Project01.main(Project01.java:45)

我需要获取 2 个数组列表(数量、价格)并将 2 的值相乘并将它们存储在一个新的数组列表中,然后找到该数组列表的最小值和最大值。

我的代码:

import java.util.*;
import java.io.*;

public class Project01 {

public static void main(String[] args) {
    ArrayList<String> Titles = new ArrayList<String>();//Declare the array lists that will be used.
    ArrayList<String> Types = new ArrayList<String>();
    ArrayList<Double> Prices = new ArrayList<Double>();
    ArrayList<Integer> Quantities = new ArrayList<Integer>();
    ArrayList<Double> Dollars = new ArrayList<Double>();
    int count = 0;//Set the counter to zero.
    Scanner in = new Scanner(System.in);//Establish the scanner so user input can be properly read.
    String database = getFile(in);//Setting the file name variable from the method below that asks the user for the file's name.
    try {
        File file = new File(database);
        Scanner inputFile = new Scanner(file);
        System.out.println();
        System.out.println("Product Summary Report");
        System.out.println("------------------------------------------------------------");
        while (inputFile.hasNextLine()) {
            getTitle(Titles, inputFile.nextLine());
            getQuantity(Quantities, inputFile.nextInt());
            inputFile.nextLine();
            getPrice(Prices, inputFile.nextDouble());
            inputFile.nextLine();
            getType(Types, inputFile.nextLine());
            System.out.println("Title: " + Titles.get(count));
            System.out.println(" Product Type: " + Types.get(count));
            System.out.println(" Price: " + Prices.get(count));
            System.out.println(" Quantity: " + Quantities.get(count));
            System.out.println();
            count++;
        }
        System.out.println("-----------------------------------------------------------------");
        System.out.println("Total products in database: " + count);
        Integer index = getLargestQuantityTitle(Quantities);
        System.out.println("Largest quantity item : " + Titles.get(index) + " (" + Types.get(index) + ")");
        Double highestTotalDollarAmount = getHighestDollarAmount(Dollars);
        System.out.println("Highest total dollar item: $" + highestTotalDollarAmount);
        Integer index2 = getSmallestQuantityTitle(Quantities);
        System.out.println("Smallest quantity item: " + Titles.get(index2) + " (" + Types.get(index2) + ")");
        System.out.println("Lowest total dollar item: ");
        System.out.println("-----------------------------------------------------------------");
        inputFile.close();
    } catch (IOException e) {
        System.out.println("There was a problem reading from " + database);

    }
    in.close();
}
private static String getFile(Scanner inScanner) {
    System.out.print("Enter database filename: ");
    String fileName = inScanner.nextLine();
    return fileName;
}
private static void getTitle(ArrayList<String> Titles, String title) { //This method is creating the array list of the titles from the input file.
    Titles.add(title);
}
private static void getType(ArrayList<String> Types, String type) { //This method is creating the array list of the types from the input file.
    Types.add(type);
}
private static void getPrice(ArrayList<Double> Prices, double price) { //This method is creating the array list of the prices from the input file.
    Prices.add(price);
}
private static void getQuantity(ArrayList<Integer> Quantities, int quantity) { //This method is creating the array list of the quantities from the input file.
    Quantities.add(quantity);
}
private static Integer getLargestQuantityItem(ArrayList<Integer> Quantities){ //This method is determining the maximum value within the quantities array list.
    return Collections.max(Quantities);
    }
private static Double getHighestPricedItem(ArrayList<Double> prices){ //This method is determining the maximum price within the prices array list.
    return Collections.max(prices);
}
private static Integer getHighestTotalDollarItem(ArrayList<Integer> Prices){ //This method is determining the maximum total value, basically the highest quantity of the item multiplied by it's price.
    return Collections.max(Prices);
}
private static Integer getSmallestQuantityItem(ArrayList<Integer> Quantities){ //This method is determining the minimum value within the quantities array list.
    return Collections.min(Quantities);
    }
private static Integer getLargestQuantityTitle(ArrayList<Integer> Quantities){
    int index = 0;
    Integer largestQuantityMainVariable = getLargestQuantityItem(Quantities);
    for (int i = 0; i < Quantities.size(); i++) {
        if (Quantities.get(i) != null && Quantities.get(i).equals(largestQuantityMainVariable)) {
            index = i;
            break;
        }
    }
    return index;
}
private static Integer getSmallestQuantityTitle(ArrayList<Integer> Quantities){
    int index2 = 0;
    Integer smallestQuantityMainVariable = getSmallestQuantityItem(Quantities);
    for (int i = 0; i < Quantities.size(); i++) {
        if (Quantities.get(i) != null && Quantities.get(i).equals(smallestQuantityMainVariable)) {
            index2 = i;
            break;
        }
    }
    return index2;
}
private static ArrayList<Double> Dollars (ArrayList<Integer> Quantities, ArrayList<Double> Prices){
    int counter=0;
    while (counter<Quantities.size()){
        ArrayList<Double> Dollars = new ArrayList<Double>();
        Dollars.add(Quantities.get(counter)*Prices.get(counter));
    counter++;
    }

    return Dollars(null, null);
}
private static Double getHighestDollarAmount(ArrayList<Double> Dollars){ //This method is determining the maximum price within the prices array list.
    return Collections.max(Dollars);
}

}

我的输出:

Enter database filename: /Desktop/proj1_input

Product Summary Report
------------------------------------------------------------
Title: The Shawshank Redemption
Product Type: DVD
Price: 19.95
Quantity: 100

Title: The Dark Knight
Product Type: DVD
Price: 19.95
Quantity: 50

Title: Casablanca
Product Type: DVD
Price: 9.95
Quantity: 137

Title: The Girl With The Dragon Tattoo
Product Type: Book
Price: 14.95
Quantity: 150

Title: Vertigo
Product Type: DVD
Price: 9.95
Quantity: 55

Title: A Game of Thrones
Product Type: Book
Price: 8.95
Quantity: 100

-----------------------------------------------------------------
Total products in database: 6
Largest quantity item : The Girl With The Dragon Tattoo (Book)
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:350)
at java.util.Collections.max(Collections.java:638)
at Project01.getHighestDollarAmount(Project01.java:120)
at Project01.main(Project01.java:45)

输入文件(.txt 文件):

The Shawshank Redemption
100
19.95
DVD
The Dark Knight
50
19.95
DVD
Casablanca
137
9.95
DVD
The Girl With The Dragon Tattoo
150
14.95
Book
Vertigo
55
9.95
DVD
A Game of Thrones
100
8.95
Book

【问题讨论】:

  • 您填写了Dollars 数组列表吗?
  • 您应该尝试遵循 Java 的驼峰式大小写约定
  • 如果您关心金钱的精确度,我怀疑您确实如此,那么您真的不应该将金钱作为双重存储。 long 或 BigDecimal 被认为是正确的方法。
  • @rbennett485 不,我刚刚发现这就是我收到错误的原因。我需要帮助正确填充 Dollars 数组列表。

标签: java arraylist max min


【解决方案1】:

我知道你有什么问题。您在 while 的每次迭代中都在 Dollars 方法中初始化 ArrayList。 更改此代码

while (counter<Quantities.size()){
        ArrayList<Double> Dollars = new ArrayList<Double>();
        Dollars.add(Quantities.get(counter)*Prices.get(counter));
        counter++;
    }

到这里

ArrayList<Double> Dollars = new ArrayList<Double>();

    while (counter<Quantities.size()){
            Dollars.add(Quantities.get(counter)*Prices.get(counter));
        counter++;
        }

所以最终的方法应该是这样的

private static ArrayList<Double> toDollars(ArrayList<Integer> quantities, ArrayList<Double> prices){
int counter=0;
ArrayList<Double> outputInDollars= new ArrayList<Double>();
while (counter<quantities.size()){
    outputInDollars.add(quantities.get(counter)*prices.get(counter));
counter++;
}

return outputInDollars;
}

我还建议您使用 for 循环,但这取决于您。尝试使用驼峰命名变量

【讨论】:

  • 美元数组列表为空。我不确定如何填充它。我以为我做到了,但显然没有。你能帮忙吗?
  • 你在 Quantities arrayList 中有什么吗?您的循环取决于数量。调试代码并检查 while 循环是否正在触发。你也没有解雇你的美元功能。我还修改了一个 Dollars 函数。将其与您的原始版本进行比较。您的旧版本会产生异常,因为您在没有停止条件的情况下递归调用它
【解决方案2】:

我没有看到主要调用 Dollars 方法(实际上乘以数量和价格的方法)。此外,您正在 while 循环中实例化 Dollars Arraylist,因此您将失去对添加到列表中的旧数据的引用。如果那是你想做的,那为什么还要有一个柜台呢?

拥有一个名为 Dollars 的方法和一个同名的属性会引起很多混乱。请不要这样做。

使用 List 而不是 ArrayList 进行引用。仅在实例化对象时使用 ArrayList。 实例属性名称应以小写字母或下划线开头。

【讨论】:

    【解决方案3】:

    Collections.max() 如果集合为空,则抛出 NoSuchElementException。这就是你的问题。您不会将任何值添加到美元列表中。 另外你从不打电话给 Dollars() 也更新你的美元功能:

    private static ArrayList<Double> Dollars (ArrayList<Integer> Quantities, ArrayList<Double> Prices){
        int counter=0;
        // create arrayList outside of the while and return it
        ArrayList<Double> Dollars = new ArrayList<Double>();
    
        while (counter<Quantities.size()){
    
            Dollars.add(Quantities.get(counter)*Prices.get(counter));
            counter++;
        }
        // you returned a call to the same function there -> recusive until death
        return Dollars;
    }
    

    【讨论】:

    • 好的,这就是我的问题。我不确定如何正确填充美元。我需要帮助。
    • 你的函数 Dollars 永远不会被调用。
    【解决方案4】:

    方法导致异常:

    private static Double getHighestDollarAmount(ArrayList<Double> Dollars) {
        return Collections.max(Dollars);
    }
    

    因为 ArrayList Dollars 是空的。

    你在这里调用那个方法:

    Double highestTotalDollarAmount = getHighestDollarAmount(Dollars);
    

    提供的列表Dollars 是空的,因为它没有在这个while 循环中使用:

    while (inputFile.hasNextLine()) {
        getTitle(Titles, inputFile.nextLine());
        getQuantity(Quantities, inputFile.nextInt());
        inputFile.nextLine();
        getPrice(Prices, inputFile.nextDouble());
        inputFile.nextLine();
        getType(Types, inputFile.nextLine());
        System.out.println("Title: " + Titles.get(count));
        System.out.println(" Product Type: " + Types.get(count));
        System.out.println(" Price: " + Prices.get(count));
        System.out.println(" Quantity: " + Quantities.get(count));
        System.out.println();
        count++;
    }
    

    所以,要么您将列表 DollarsPrices 混合并想调用:

    Double highestTotalDollarAmount = getHighestDollarAmount(Prices);
    

    或者您忘记在某处“填写”Dollars 列表。

    编辑:

    我已经更新了你的Dollars 方法:

     private static List<Double> getTotalPrices(List<Integer> quantities, List<Double> prices){
          List<Double> totalPrices = new ArrayList<>();
          for (int i = 0; i < quantities.size(); i++) {
               totalPrices.add(quantities.get(i) * prices.get(i));
          }
          return totalPrices;
     }
    

    我做了以下更改:

    1. 我已将该方法重命名为getTotalPrices,因为此名称比Dollars 更具描述性,并且它遵循Java Naming Conventions(方法名称应以小写字母开头)
    2. 我已将类型从 ArrayList 更改为 List,因为您应该始终使用 program to an interface 而不是特定类型
    3. 由于命名约定,我更改了参数的名称
    4. 我已将 while 循环替换为 for 循环,因为在这种情况下它们会更好(遍历列表)
    5. 我已将返回值更改为新列表,而不是递归调用(这会造成更多麻烦)

    【讨论】:

    • 我没有填写美元,需要帮助。
    • @SeumasFrew 这和鲨鱼的答案都包含你需要的一切。请仔细阅读。
    猜你喜欢
    • 2019-06-13
    • 2018-03-12
    • 2015-05-26
    • 2020-03-16
    • 1970-01-01
    • 2010-12-17
    • 1970-01-01
    • 2017-05-24
    • 2022-12-12
    相关资源
    最近更新 更多