Java Stream基于不同ID的值的平均值

时间:2019-02-16 17:45:53

标签: java java-stream

我有一个叫做Tag的类。

public class Tag {
    String tag_id;
    int x_pos;
    int y_pos;
    int z_pos;
    public String getTag_id() {
        return tag_id;
    }
    public void setTag_id(String tag_id) {
        this.tag_id = tag_id;
    }
    public int getX_pos() {
        return x_pos;
    }
    public void setX_pos(int x_pos) {
        this.x_pos = x_pos;
    }
    public int getY_pos() {
        return y_pos;
    }
    public void setY_pos(int y_pos) {
        this.y_pos = y_pos;
    }
    public int getZ_pos() {
        return z_pos;
    }
    public void setZ_pos(int z_pos) {
        this.z_pos = z_pos;
    }

    public String toString()
    {
        return this.tag_id +" "+this.x_pos+" "+this.y_pos+" "+this.z_pos;
    }


}

现在我有一个Tag数组列表。

ArrayList<Tag> tag_info = new ArrayList<>();

标签ID可以是A,B,C或其他任何内容。它是动态的,不是固定的。 我需要获取tag_info的x_pos,y_pos和z_pos的平均值。数组列表的大小也是动态的,范围在60-70之间。我已经使用循环编写了所有内容,但想使用Stream对其进行转换。

我使用:

提取了唯一ID。
Stream<Tag> a = tag_info.stream().filter(distinctByKey(Tag::getTag_id));

但是现在我不想对所有值进行循环并获得平均值。有没有更简单的方法?

2 个答案:

答案 0 :(得分:1)

使用Collectors::averagingDouble

    Double xAvg = tag_info.stream()
            .collect(Collectors.averagingDouble(Tag::getX_pos));
    Double yAvg = tag_info.stream()
            .collect(Collectors.averagingDouble(Tag::getY_pos));
    Double zAvg = tag_info.stream()
            .collect(Collectors.averagingDouble(Tag::getZ_pos));

此外,如果您想按每个tag_id获取平均值,请使用groupingBy

    Map<String, Double> map = tags.stream()
            .collect(groupingBy(Tag::getTag_id,
                    averagingDouble(Tag::getX_pos)));

答案 1 :(得分:0)

也许总计缓存可以帮助避免重新计算所有值,例如:

  • 带有long total_xlong total_ylong total_z的新类TagsList
  • 添加标签后,将其从TagsList中删除,然后对标签总数进行适当的修改
  • 可以修改标记以接受ChangeEventListener(即TagList),当修改pos_x,pos_y或pos_z时,侦听器会收到通知,因此TagList可以更新其总值。
  • getAverage_Pos_x只是total_x / numberOfTags