2015-03-03 37 views
6

我正在写一个小程序来生成一些随机数,并希望得到有关它们的统计信息。我有一个List<AtomicInteger>,我想用它来输出一些信息。Java 8编译器错误与流和减少

我试着用下面的代码来减少清单其总(例如,所有的AtomicIntegers的值的总和):

// not my real initialization code, just for illustration purposes 
List<AtomicInteger> values = new ArrayList<>(); 
for(int i = 0; i < 10; i++) { 
    values.add(new AtomicInteger()); 
} 

// this is the problematic reduce 
int total = values 
    .parallelStream() 
    .reduce(0, 
     (currentValue, currentAtomic) 
      -> currentValue + currentAtomic.get(), 
     (combiner1, combiner2) -> combiner1 + combiner2); 

我的IDE(的IntelliJ)没有问题,这条线的所有,但我目前的javac版本(1.8.0_31)这条线会导致一个NullPointerException编译器:

An exception has occurred in the compiler (1.8.0_31). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you. 
java.lang.NullPointerException 
    at com.sun.tools.javac.code.Types.isConvertible(Types.java:290) 
    at com.sun.tools.javac.comp.Check.assertConvertible(Check.java:922) 
    at com.sun.tools.javac.comp.Check.checkMethod(Check.java:876) 
    at com.sun.tools.javac.comp.Attr.checkMethod(Attr.java:3838) 
    at com.sun.tools.javac.comp.Attr.checkIdInternal(Attr.java:3615) 
    at com.sun.tools.javac.comp.Attr.checkMethodIdInternal(Attr.java:3522) 
    at com.sun.tools.javac.comp.Attr.checkMethodId(Attr.java:3501) 
    at com.sun.tools.javac.comp.Attr.checkId(Attr.java:3488) 
    at com.sun.tools.javac.comp.Attr.visitSelect(Attr.java:3370) 
    at com.sun.tools.javac.tree.JCTree$JCFieldAccess.accept(JCTree.java:1897) 
    at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
    at com.sun.tools.javac.comp.Attr.visitApply(Attr.java:1843) 
    at com.sun.tools.javac.tree.JCTree$JCMethodInvocation.accept(JCTree.java:1465) 
    at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
    at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:649) 
    at com.sun.tools.javac.comp.Attr.visitVarDef(Attr.java:1093) 
    at com.sun.tools.javac.tree.JCTree$JCVariableDecl.accept(JCTree.java:852) 
    at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
    at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676) 
    at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:692) 
    at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:1142) 
    at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:909) 
    at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
    at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676) 
    at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:1035) 
    at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:778) 
    at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:607) 
    at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:676) 
    at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:4342) 
    at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4252) 
    at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:4181) 
    at com.sun.tools.javac.comp.Attr.attrib(Attr.java:4156) 
    at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1248) 
    at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:901) 
    at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:860) 
    at com.sun.tools.javac.main.Main.compile(Main.java:523) 
    at com.sun.tools.javac.main.Main.compile(Main.java:381) 
    at com.sun.tools.javac.main.Main.compile(Main.java:370) 
    at com.sun.tools.javac.main.Main.compile(Main.java:361) 
    at com.sun.tools.javac.Main.compile(Main.java:56) 
    at com.sun.tools.javac.Main.main(Main.java:42) 

我知道,可能有其他的方式来完成相同的减少,但是我真的很想留住并行流的性质(正弦我原来的代码有很多值)。任何人都可以建议我另一个并行减少选项,不会崩溃我的编译器,可以实现相同的结果?

我也想知道这是否只是我遇到的问题,或者如果其他人可以重现此编译器错误。

+0

确认用javac 1.8.0_31。 – 2015-03-03 09:10:13

+4

是的,我也确认了javac 1.8.0_31,你发现了一个bug,你应该报告它。 – shazin 2015-03-03 09:11:24

+1

可能是https://bugs.openjdk.java.net/browse/JDK-8068398或https://bugs.openjdk.java.net/browse/JDK-8046357或https://bugs.openjdk的副本.java.net/browse/JDK-8072751 – Marco13 2015-03-03 09:19:44

回答

3

或者,而不是使用reduce,您可以使用mapToIntsum

int total = values.stream().mapToInt(AtomicInteger::get).sum(); 
1

版本不会崩溃编译:

// not my real initialization code, just for illustration purposes 
     List<AtomicInteger> values = new ArrayList<>(); 
     for(int i = 0; i < 10; i++) { 
      values.add(new AtomicInteger()); 
     } 

// this is the problematic reduce 
     BiFunction<Integer, AtomicInteger, Integer> accumulator = 
       (currentValue, currentAtomic) -> currentValue + currentAtomic.get(); 
     BinaryOperator<Integer> combiner = (combiner1, combiner2) -> combiner1 + combiner2; 
     int total = values 
       .parallelStream() 
       .reduce(0, accumulator, combiner); 
+2

你可以删除组合器,并用''Integer.sum'替换它,使用方法引用:'.reduce(0,accumulator,Integer :: sum);' – 2015-03-03 09:15:50

+0

由于某种原因,只是像这样分裂它不会发生在我身上在所有。谢谢! – mhlz 2015-03-03 09:16:52

+3

@mhlz分裂出去是没有必要的,你只需要指定参数类型:'。降低(0, \t \t(整数CurrentValue的,的AtomicInteger currentAtomic) \t \t - > CurrentValue的+ currentAtomic.get(), \t \t Integer :: sum)'也可以。 – 2015-03-03 09:22:13