在ArrayList中查找min,max,avg

时间:2015-10-07 18:48:36

标签: java arraylist max average min

我无法隔离每个不同的名称并计算其平均值,平均值,最大值。如果只是为一个列表执行它,我没有问题,但是当我必须使用某些名称中的值时,它会变得棘手。

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测试用例,因此我不能使用通过方法声明的值,而是必须能够传递给定的任何测试用例。

2 个答案:

答案 0 :(得分:2)

使用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}

答案 1 :(得分:0)

使用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();

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

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

编辑:

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

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);

此解决方案仍然需要您遍历原始数据。将州名和数字分开(可能是正则表达式),然后将每一段数据放入正确的位置。

希望这有帮助!

P.S。如果您告诉我们您正在运行的Java版本,我们可以优化结果以利用最新的可用功能。这将编译至少6,也许5,因此如果你运行7或8,它将比它需要更详细。