使用Java流而不是for循环会跳过代码执行

使用Java流而不是for循环会跳过代码执行,java,java-stream,weka,moa,Java,Java Stream,Weka,Moa,将一堆for循环代码切换为使用并行流显然会导致忽略代码的某些部分 我正在使用MOA和Weka与Java 11一起运行一个简单的推荐引擎示例,从MOA.tasks.evaluateOnlineRecommender的源代码中获取线索,它使用MOA的内部任务设置来测试MOA提供的有偏正则化增量同时矩阵分解(BRISMF)实现的准确性。我没有使用MOA准备好的MovielensDataset类,而是切换到了Weka的实例,以寻找应用Weka的ML工具的前景 处理大约一百万个实例(我使用的是Moviel

将一堆for循环代码切换为使用并行流显然会导致忽略代码的某些部分

我正在使用MOA和Weka与Java 11一起运行一个简单的推荐引擎示例,从
MOA.tasks.evaluateOnlineRecommender
的源代码中获取线索,它使用MOA的内部任务设置来测试MOA提供的有偏正则化增量同时矩阵分解(BRISMF)实现的准确性。我没有使用MOA准备好的
MovielensDataset
类,而是切换到了Weka的
实例
,以寻找应用Weka的ML工具的前景

处理大约一百万个实例(我使用的是Movielens 1M数据集)所需的时间约为13-14分钟。为了看到改进,我想在并行流上运行它,当任务在大约40秒内完成时,我开始怀疑。我发现,
BRISMFPredictor.predictRating
在并行流的主体中总是产生0。以下是两种情况的代码:

初始化代码:

import com.github.javacliparser.FileOption;
import com.github.javacliparser.IntOption;

import moa.options.ClassOption;
import moa.recommender.predictor.BRISMFPredictor;
import moa.recommender.predictor.RatingPredictor;
import moa.recommender.rc.data.RecommenderData;
import weka.core.converters.CSVLoader;

。。。在
main()
(Weka的
CSVLoader
有一个怪癖,需要我用
+
替换默认的
分隔符)

现在,交替使用以下代码段:

for (var instance : dataset) {
    var user = (int) instance.value(0);
    var item = (int) instance.value(1);
    var rating = instance.value(2);

    double predictedRating = predictor.predictRating(user, item);

    System.out.printf("User %d | Movie %d | Actual Rating %d | Predicted Rating %f%n",
                    user, item, Math.round(rating), predictedRating);
}
(现在是所有事情的noob):

现在我决定见鬼,也许这个操作不能并行完成,我将它切换为使用
stream()
。即使如此,该段似乎也被完全忽略,因为每次输出都是0.0

dataset.stream().forEach(instance -> {
    var user = (int) instance.value(0);
    var item = (int) instance.value(1);
    var rating = instance.value(2);

    double predictedRating = predictor.predictRating(user, item);

    System.out.printf("User %d | Movie %d | Actual Rating %d | Predicted Rating %f%n",
                    user, item, Math.round(rating), predictedRating);
});
我已尝试从运行中删除打印语句,但无效

显然,在第一种情况下,我在大约13分钟内得到了由实际和预测评级组成的预期输出行,但在第二种情况下,我发现预测评级为0.0,执行时间很短。有什么我错过的吗


编辑:使用
dataset.forEach()
做同样的事情。也许是lambdas的一个怪癖?

数据集的类型是什么??上面的问题是关键+如果你使用数据集,你会得到什么。forEach?以及什么是
预测器。predictRating
的定义?这将非常有帮助。@mushi当你说“结果都是0.0”时,你到底指的是什么<代码>预测分级?
for (var instance : dataset) {
    var user = (int) instance.value(0);
    var item = (int) instance.value(1);
    var rating = instance.value(2);

    double predictedRating = predictor.predictRating(user, item);

    System.out.printf("User %d | Movie %d | Actual Rating %d | Predicted Rating %f%n",
                    user, item, Math.round(rating), predictedRating);
}
dataset.parallelStream().forEach(instance -> {
    var user = (int) instance.value(0);
    var item = (int) instance.value(1);
    var rating = instance.value(2);

    double predictedRating = predictor.predictRating(user, item);

    System.out.printf("User %d | Movie %d | Actual Rating %d | Predicted Rating %f%n",
                    user, item, Math.round(rating), predictedRating);
});
dataset.stream().forEach(instance -> {
    var user = (int) instance.value(0);
    var item = (int) instance.value(1);
    var rating = instance.value(2);

    double predictedRating = predictor.predictRating(user, item);

    System.out.printf("User %d | Movie %d | Actual Rating %d | Predicted Rating %f%n",
                    user, item, Math.round(rating), predictedRating);
});