在 Java 流中执行归约操作时出现异常

我是 Java 8 的新手,在下面的示例中,我创建了一个 Map,其键值为 String,值为整数的 ArrayList。


Map<String,List<Integer>> mapLstInteger=new HashMap<String,List<Integer>>() {

            {

                put("A",Arrays.asList(1,2,3));

                put("B",Arrays.asList(4,5,6));

                put("C",Arrays.asList(7,8,9));

            }

        };

我编写了下面的代码来针对每个键执行 arrayList 元素的总和,并试图将总和值存储在单独的 ArrayList 中。


List<Integer> sumLst=mapLstInteger.entrySet().stream().map(e->e.getValue())

        .reduce((inputLst, outputLst)->{

            int sum=0;

            for(int count=0;count<inputLst.size();count++)

            {

                sum=sum+inputLst.get(count);

            }

            outputLst.add(sum);

            return outputLst;

        }).get();

当我尝试执行以下代码时,我遇到了异常。


com.calculation.sum.client 的 java.util.AbstractList.add(AbstractList.java:108) 的 java.util.AbstractList.add(AbstractList.java:148) 的线程“main”java.lang.UnsupportedOperationException 中的异常。 Client.lambda$1(Client.java:43) at java.util.stream.ReduceOps$2ReducingSink.accept(ReduceOps.java:123) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1696) 在 java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) 在 java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)在 java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) 在 java.util.stream.java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)。ReferencePipeline.reduce(ReferencePipeline.java:479) 在 com.calculation.sum.client.Client.main(Client.java:37)


任何人都可以让我知道我在上面的代码中做错了什么>


阿晨1998
浏览 203回答 3
3回答

哆啦的时光机

首先,您使用Arrays::asList的是记录为返回由指定数组支持的固定大小列表,我认为固定大小应该告诉您您做错了什么。HashMap比您使用创建就地的反模式- 通过创建扩展的匿名内部类HashMap,通过 that&nbsp;Map<String,List<Integer>> mapLstInteger=new HashMap<String,List<Integer>>()....。比,你违反了 的规范reduce,它应该一直返回一个新的对象,但你总是放入outputLst.比,Map当你只关心它的值时,你正在创建一个 -List<List<Integer>>在这种情况下创建一个。根据您的代码,即使您在代码下面编写的用于针对每个键对 arrayList 元素求和的句子也不正确。如果我是你,我会在我想要实现的实际目标上下定决心,然后尝试去做。

慕的地10843

发生这种情况是因为您使用的AbstractList是由Arrays.asList.该List<T>抽象实现不允许添加或删除元素。public void add(int index, E element) {&nbsp; &nbsp; throw new UnsupportedOperationException();}但无论如何,回到你的问题。您也可以通过 custom获得您想要的东西Collector,您可以在其中提供您的自定义List<T>实现,无论是ArrayList,LinkedList还是您觉得更好的任何东西。mapLstInteger.values()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collector.of(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;() -> new ArrayList<>(),&nbsp; // Supplier&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(output, toSumList) -> {&nbsp; // Accumulator&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;output.add(toSumList.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.mapToInt(Integer::intValue)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.sum());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;},&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// The Combiner implementation will be called&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// in case of a "parallel" Stream.&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// No need to worry about it here.&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// But in case, we would need to merge the partial results&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(output, partial) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; output.addAll(partial);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return output;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;));更简洁的版本是mapLstInteger.values()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.map(l -> l.stream().mapToInt(Integer::intValue).sum())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.collect(Collectors.toCollection(ArrayList::new));这将正确输出[6, 15, 24]

茅侃侃

您应该执行以下操作:&nbsp;&nbsp;&nbsp;&nbsp;mapLstInteger.values().stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flatMapToInt(list&nbsp;->&nbsp;list.stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(Objects::nonNull) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.mapToInt(Integer::intValue)).sum();添加了过滤器以确保在空整数的情况下不会获得空指针。作为一般规则,如果您被迫在流中使用常规循环,您可能做错了什么。通过将 int 列表更改为 int 值,我们可以轻松地求和,如上所示。最初误解了这个问题,认为您想要总和,唉,这是针对实际问题的更新解决方案:&nbsp;&nbsp;&nbsp;&nbsp;mapLstInteger.values().stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(list&nbsp;->&nbsp;list.stream() &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(Objects::nonNull) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.mapToInt(Integer::intValue).sum()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java