简体   繁体   English

如何从 Java 中的列表中找到过滤元素的平均值

[英]How do I find the average of filtered elements from list in Java

I wish to find the average of sales by a particular branch in a given year.我希望找到给定年份特定分支机构的平均销售额。 There is a list which has all the branches and all the years of sale.有一个列表,其中包含所有分支机构和所有销售年份。 I've tried to use IntStream to filter the elements with the required year and branch but I'm unable to find the average, There is an error showing in indexOfSaleInTheYear.size(), and I am not sure if the average part code is correct.我尝试使用 IntStream 来过滤具有所需年份和分支的元素,但我无法找到平均值,indexOfSaleInTheYear.size() 中显示错误,我不确定平均值部分代码是否为正确的。 Please help.请帮忙。 Thank You.谢谢你。

Scanner avgSale = new Scanner(System.in);
    System.out.println("Please enter the year for average sale: \n");
    int yearEntered = avgSale.nextInt();

    Scanner branchNameForAvg = new Scanner(System.in);
    System.out.println("Please enter the branch name whose average sale is to be found, case sensitive: \n");
    String branchNameEntered = branchNameForAvg.nextLine();

    Stream<Integer> indexOfSalesInTheYear = IntStream.of(0, Sale.allValues.size()).boxed()
            .filter(i -> Sale.allYears.get(i).equals(yearEntered))
            .filter(i -> Sale.allBranches.get(i).equals(branchNameEntered));
    
    int sum = 0;
    for(int j = 0; j < indexOfSalesInTheYear.size(); j++){
        sum += j;
    }
    double avgSaleFinal = sum/indexOfSalesInTheYear.size();

    System.out.println("The average sale for the year " + yearEntered + " is " + avgSaleFinal + ".");
    }

Here is how I would approach it.这是我将如何处理它。 Instead of separate lists of values, years, and branches, have a list of objects that contain these fields:有一个包含这些字段的对象列表,而不是单独的值、年份和分支列表:

record Sale(int value, int year, String branch) {
}

Here I am using a record but if you prefer, need to have mutable Sale instances, or are using an earlier version of Java, you could adapt this code to use classes with ordinary getters and setters.在这里,我使用的是record ,但如果您愿意,需要具有可变的Sale实例,或者正在使用 Java 的早期版本,您可以调整此代码以使用具有普通 getter 和 setter 的类。

List<Sale> sales = List.of(
    new Sale(12, 2020, "east"),
    new Sale(15, 2020, "west"),
    new Sale(13, 2020, "east"),
    new Sale(16, 2020, "west"),
    new Sale(14, 2020, "east"),
    new Sale(17, 2020, "west"),
    new Sale(18, 2021, "east"),
    new Sale(19, 2021, "west"));

double averageOfSales(int year, String branchName) {
    OptionalDouble average = sales.stream()
        .filter(sale -> sale.year() == year)
        .filter(sale -> sale.branch().equals(branchName))
        .mapToInt(sale -> sale.value())
        .average();
    return average.orElseThrow(() ->
        new NoSuchElementException("no matching year and branch"));
}

You may want to simply return the OptionalDouble or throw a different exception;您可能只想返回OptionalDouble或抛出一个不同的异常; it all depends on how you want to handle the case where there are no values for the year and branch name provided.这完全取决于您要如何处理没有提供年份和分支名称的值的情况。 You may even want to just return 0.0 or NaN or -1.0 or some other sentinel value in that case.在这种情况下,您甚至可能只想return 0.0或 NaN 或 -1.0 或其他一些标记值。

There is no need to sum the values yourself or divide by the number of values to find the mean since IntStream already has methods for finding the sum or average.不需要自己对值求和或除以值的数量来求平均值,因为IntStream已经有求和或求平均值的方法。

Keeping the different pieces of data broken out in separate, parallel structures is a common pattern among new Java programmers but it really goes against the concept of object oriented programming or even just abstract data types.保持不同的数据片段分开,并行结构是新的 Java 程序员的常见模式,但它确实违背了面向 object 的编程或什至只是抽象数据类型的概念。 You don't need to keep separate collections of simple values;您不需要单独保留 collections 的简单值; you can invent your own types that encompass the value, year, branch, month, house number, post code, and whatever else you want to model as part of the domain of the data you're working with.您可以创建自己的类型,包括值、年份、分支机构、月份、门牌号、邮政编码以及您想要的任何其他类型 model 作为您正在使用的数据域的一部分。

In your existing code, you are never iterating the allValues list.在您现有的代码中,您永远不会迭代allValues列表。 Since you are using streams you can do this.由于您使用的是流,因此您可以这样做。

double average = IntStream.of(0, Sale.allValues.size()-1) // go up to the last index only
                .filter(i -> Sale.allYears.get(i).equals(yearEntered))
                .filter(i -> Sale.allBranches.get(i).equals(branchNameEntered))
                .mapToDouble(i -> Sale.allValues.get(i)) // now you have every sale value for yearEntered and branchNameEntered
                .average().orElse(-1); // or if not present, throw error, or get the optional, etc

Really you shouldn't have separate lists, you should have a list of Sale objects.实际上,您不应该有单独的列表,您应该有一个 Sale 对象列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Java LinkedList中找到平均值? - how do I find the average in a Java LinkedList? 如何从另一个列表中创建一个列表,该列表由 Java 中的对象属性过滤? - How do I create a List from another List filtered by an object's property in Java? 如何找到列表java的平均值 - how to find average of a List java 如何使用 JAVA 流从对象列表中查找平均值 - How to find average from a list of objects using JAVA streams 如何从 a.txt 文件中读取内容,然后在 Java 中找到所述内容的平均值? - How do I read content from a .txt file and then find the average of said content in Java? 如何在Java的ArrayList中找到平均值和最高评分? - How do I find the average and the top grade in an ArrayList in Java? 我的问题是Java中的链表? 我如何使用链表中的元素(拉巴特)来实现平均价格? - My problem is with linked list in Java? How can I use the elements (rabat) from linked list to achieve average price? Java Micro基准测试从列表中找到平均值 - java micro benchmark to find average from list 如何从对象列表中找到最小的变量? (JAVA) - How do I find the smallest variable from a list of objects? (JAVA) 如何在Java 8中过滤对象列表并返回特定的过滤对象 - How do i filter a list of object and return that particular filtered object in Java 8
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM