我试图理解新的Java8流API。
http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
我找到了使用collect API查找数字平均值的示例。但我觉得,使用reduce()也可以做到这一点。
public class Test {
public static void main(String[] args) {
// Using collect
System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.collect(Averager::new, Averager::accept, Averager::combine)
.average());
// Using reduce
System.out.println(Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.reduce(new Averager(), (t, u) -> {
t.accept(u);
return t;
}, (t, u) -> {
t.combine(u);
return t;
}).average());
}
private static class Averager {
private int total = 0;
private int count = 0;
public Averager() {
// System.out.println("Creating averager");
}
public double average() {
// System.out.println("Finding average");
return count > 0 ? ((double) total) / count : 0;
}
public void accept(int i) {
// System.out.println("Accepting " + i);
total += i;
count++;
}
public void combine(Averager other) {
// System.out.println("Combining the averager : " + other);
total += other.total;
count += other.count;
}
@Override
public String toString() {
return "[total : " + total + ", count: " + count + "]";
}
}
}
reduce
和collection
之间的区别在于,collection
是一种增强的约简形式,可以并行处理可变对象。collection
算法对各种结果对象进行线程限制,这样即使它们不是线程安全的,也可以安全地进行更改。这就是averager
使用collection
工作的原因。对于使用reduce
的顺序计算,这通常并不重要,但是对于并行计算,它将给出错误的结果,正如您所观察到的。
关键的一点是,reduce
只要处理的是值,而不是可变对象,它就可以工作。您可以通过查看reduce
的第一个参数来了解这一点。示例代码传递new Averager()
,这是一个单个对象,在并行约简中多个线程将其用作标识值。并行流的工作方式是将工作负载拆分为由单个线程处理的段。如果多个线程正在突变同一个(非线程安全的)对象,那么应该清楚为什么这会导致不正确的结果。
可以使用reduce
来计算平均值,但您需要使累加对象是不可变的。考虑对象immutableaverager
:
static class ImmutableAverager {
private final int total;
private final int count;
public ImmutableAverager() {
this.total = 0;
this.count = 0;
}
public ImmutableAverager(int total, int count) {
this.total = total;
this.count = count;
}
public double average() {
return count > 0 ? ((double) total) / count : 0;
}
public ImmutableAverager accept(int i) {
return new ImmutableAverager(total + i, count + 1);
}
public ImmutableAverager combine(ImmutableAverager other) {
return new ImmutableAverager(total + other.total, count + other.count);
}
}
注意,我调整了accept
和combine
的签名,以返回一个新的immutableaverager
而不是更改this
。(这些更改还使方法与reduce
的函数参数相匹配,因此我们可以使用方法引用。)您可以使用immutableaverager
,如下所示:
double average = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.parallel()
.reduce(new ImmutableAverager(),
ImmutableAverager::accept,
ImmutableAverager::combine)
.average();
System.out.println("Average: "+average);
与reduce
一起使用不可变值对象应该会并行地给出正确的结果。
最后,请注意,IntStream
和DoubleStream
具有SummaryStatistics()
方法,而Collectors
具有AveragingDouble
、AveragingInt
和AveragingLong
方法可以为您执行这些计算。然而,我认为问题更多的是关于收集和减少的机制,而不是关于如何最简洁地做平均。
我一直在寻找,没有找到一个简单的问题和答案堆栈溢出寻找一个数组的平均值。 这是我的阵列 我最初以为这个问题的答案是这样的: 然而,这给了我一个NaN的输出。 然后我尝试了这个: 这给了我68的输出。(我不知道为什么)。 所以我有两个问题。1。为什么我的输出是68?和2。有人能帮我找到数组的平均值吗?
我有: 我试过了,但似乎不对:
问题内容: 我必须在Python中找到列表的平均值。到目前为止,这是我的代码 我已经知道了,所以它可以将列表中的值相加,但是我不知道如何将其划分为它们? 问题答案: 在Python 3.4+上,你可以使用 statistics.mean() 在旧版本的Python上,你可以执行 在Python 2上,你需要转换len为浮点数才能进行浮点数除法 无需使用。它慢得多,并已在Python 3 中删除。
我似乎无法从用户输入的分数中计算出平均分数。我也不能让它停止例外输入大于100或小于0。有人能告诉我我做错了什么吗?谢谢
我正在尝试使用用户输入将数字放入一个数组,然后找到这些数字的平均值,也找到哪些数字大于平均值。这些数字进入一个数组,但当我试图求平均数时,我无法求出平均数,以及哪些数字大于平均数,因为对于试图求出大于平均数的数字的部分,并非所有变量都是可见的。但是,当我允许这个部分看到所有的变量(don't But{}围绕某些部分)时,它会找到每一个数的平均值。现在,它为每个数字打印平均值,而为大于平均值的数字打
问题内容: 我正在尝试从数据集中返回总计/平均值行,其中包含某些字段的SUM和其他字段的AVG。 我可以通过以下方式在SQL中执行此操作: 我将其转换为SQLAlchemy的尝试如下: 但这是错误的: 问题答案: 您应该使用类似: 您不能在这里使用,因为SqlAlchemy试图找到一个将函数结果放入的字段,但是它失败了。