【问题标题】:Finding min, max, avg in ArrayList在 ArrayList 中查找最小值、最大值、平均值
【发布时间】:2016-01-05 03:38:42
【问题描述】:

我无法隔离每个不同的名称并计算它们的 avg、min、max。如果它只是为一个列表做这件事,我没有问题,但是当我必须只使用某些名称中的值时,它就变得棘手了。

public static ArrayList<Double> summarizeData (
    ArrayList<String> names, 
    ArrayList<Double> values,  
    ArrayList<String> categories, 
    int operation)
{
}

所以为了找到平均值,我会做类似的事情:

            //calculate sum of all array elements
            int sum = 0;

            for(int i=0; i < summarizeData.length ; i++)
                    sum = sum + summarizeData[i];

            //calculate average value
            double average = sum / summarizeData.length;

我拥有的价值观列表如下:

Utah        5
Nevada      6
California  12
Oregon      8
Utah        9
California  10
Nevada      4
Nevada      4
Oregon      17
California  6

这些值来自 Junit 测试用例,因此我不能使用通过方法声明的值,而是它们必须能够通过任何给定的测试用例。

【问题讨论】:

  • 这是什么编程语言? Java 还是 C#?
  • 对不起....这是Java

标签: java arraylist max average min


【解决方案1】:

这些类型的计算在 Java 8 中变得相当容易。假设您有以下包装类来包装您的数据:

class Data {
    final String name;
    final int value;

    public Data(String name, int value) {
        this.name = name;
        this.value = value;
    }
}

你现在可以运行了:

Stream.of(new Data("Utah"        ,5 ),
          new Data("Nevada"      ,6 ),
          new Data("California"  ,12),
          new Data("Oregon"      ,8 ),
          new Data("Utah"        ,9 ),
          new Data("California"  ,10),
          new Data("Nevada"      ,4 ),
          new Data("Nevada"      ,4 ),
          new Data("Oregon"      ,17),
          new Data("California"  ,6 ))
      .collect(Collectors.groupingBy(
          d -> d.name,
          Collectors.summarizingInt(d -> d.value)))
      .forEach((name, summary) -> System.out.println(name + ": " + summary));

产量:

Oregon: IntSummaryStatistics{count=2, sum=25, min=8, average=12.500000, max=17}
California: IntSummaryStatistics{count=3, sum=28, min=6, average=9.333333, max=12}
Utah: IntSummaryStatistics{count=2, sum=14, min=5, average=7.000000, max=9}
Nevada: IntSummaryStatistics{count=3, sum=14, min=4, average=4.666667, max=6}

【讨论】:

    【解决方案2】:

    使用 ArrayLists 的简单版本可能如下:

    List<Integer> ints = new ArrayList<Integer>(); 
    
    // Populate the list with some stuff
    ints.add(5);
    ints.add(20);
    
    int sum = 0;
    
    for (Integer anInt : ints) { // For each Integer in ints
        sum += anInt; // Add it's value to the sum
    }
    
    double average = sum / ints.size();
    

    注意使用 java 的 for-each 或增强的 for 循环用于 ArrayList,这大大简化了迭代。另请注意,ArrayList 不能接受原始类型,因为它是泛型类型,因此我们必须利用自动装箱并使用装箱类型Integer。最后,注意 ArrayList 对象被声明为 List,但被实例化为 ArrayList

    如果您的值是包含整数的字符串。然后在你的循环中,你必须将它们分开。正则表达式将是一个很好的工具。快速搜索后,这里接受的答案看起来解决得很好number out of string in java

    编辑:

    这个答案太简单了,因为它不关心数据的上下文是什么。如果您想让每个州都有自己的一组统计数据。您可以将它们存储在 Map&lt;String, Integer&gt; 中,以将每个状态的总和与该状态的名称配对。

    Map<String, Integer> stateSums = new HashMap<String, Integer>();
    
    stateSums.put("Oregon", 17);
    stateSums.put("Utah", 9); //etc
    

    请记住,如果它的键已经存在,put 方法将覆盖现有值。因此,如果您想为现有的 oregon 键添加一个新值,您可以执行以下操作:stateSums.put("Oregon", stateSums.get("Oregon") + 8);

    假设您想对它们进行排序,但将它们的所有值完全分开!你也可以这样做:

    Map<String, ArrayList<Integer>> stateValues = new HashMap<String, ArrayList<Integer>>
    
    // Unless you can affirmatively determine whether or not this key
    // already exists or not, you should check before each use to make sure
    // you don't accidentally use a list that isn't created yet, or 
    // over-write one with data with a new empty one
    if (!stateValues.containsKey("Oregon")) {
        stateValues.put("Oregon", new ArrayList<>()); // It wasn't, create,
    }
    stateValues.get("Oregon").add(17);
    stateValues.get("Oregon").add(8);
    

    此解决方案仍需要您遍历原始数据。将州名和数字分开(可能通过正则表达式),然后将每条数据放在适当的位置。

    希望这会有所帮助!

    附:如果您告诉我们您为此运行的是什么版本的 java,我们可以优化结果以利用最新的可用功能。这将在至少 6 甚至 5 上编译,因此比运行 7 或 8 时需要的更冗长。

    【讨论】:

    • 所以我必须为特定名称执行此操作.....例如添加或平均犹他州名称下的所有值。这样可以吗?
    • 我对答案进行了更新,试图进一步解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 2014-07-03
    相关资源
    最近更新 更多