2015-03-03 19 views
6

Sto scrivendo un piccolo programma per generare alcuni numeri casuali e volevo ottenere informazioni statistiche su di essi. Ho un List<AtomicInteger> che voglio usare per l'output di alcune informazioni.Errore del compilatore Java 8 con Stream e riduzione

Ho provato ad utilizzare seguente codice per ridurre la lista per la sua totale (ad esempio, la somma dei valori di tutte le 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); 

mio IDE (IntelliJ) non ha problemi con questa linea a tutti ma con il mio attuale javac versione (1.8.0_31) questa linea si traduce in una NullPointerException nel compilatore:

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) 

so che probabilmente ci sono altri modi per ottenere lo stesso riducono, ma mi piacerebbe davvero mantenere il parallelo natura del flusso (sinc e il mio codice originale ha molti valori). Qualcuno può suggerirmi un'altra opzione di riduzione parallela che non bloccherà il mio compilatore e può ottenere lo stesso risultato?

Vorrei anche sapere se questo è solo un problema che sto incontrando o se altre persone possono riprodurre questo bug del compilatore.

+0

confermata con javac 1.8.0_31. –

+4

Sì, ho confermato anche javac 1.8.0_31, hai trovato un bug e dovresti segnalarlo. – shazin

+1

Potrebbe tuttavia essere un duplicato di https://bugs.openjdk.java.net/browse/JDK-8068398 o https://bugs.openjdk.java.net/browse/JDK-8046357 o https: //bugs.openjdk .java.net/browse/JDK-8072751 – Marco13

risposta

3

In alternativa, invece di usare reduce, è possibile utilizzare mapToInt e sum:

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

versione che non va in crash compilatore:

// 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

È possibile rimuovere il combinatore e sostituirlo con 'Integer.sum' usando un riferimento al metodo:' .reduce (0, accumulator, Integer :: sum); ' –

+0

Per qualche motivo non è stato sufficiente suddividerlo in questo modo affatto. Grazie! – mhlz

+3

@mhlz Splitting fuori non è necessario, è sufficiente specificare i tipi di parametri: '.reduce (0, \t \t (Integer CurrentValue, AtomicInteger currentAtomic) \t \t -> CurrentValue + currentAtomic.get(), \t \t Numero intero :: sum) 'funziona anche. –