简体   繁体   English

处理封闭 scope 中定义的局部变量的流问题必须是最终的

[英]working with streams problem of Local variable defined in an enclosing scope must be final

i have this algorithm that i want to change it with parallel streams so it makes less time for the calculation, but when i did it i got the error Local variable defined in an enclosing scope must be final for realiseValeur, nbValid and invalidite.So how can i work with parelle streams in this algorithm.我有这个算法,我想用并行流来改变它,这样计算的时间就更少了,但是当我这样做时,我得到了错误 Local variable defined in an enclosure scope must be final for realiseValeur, nbValid 和 invalidite。那么如何我可以在这个算法中使用 parelle 流吗? This is my algorithm in which i want to work with parallelstreams:这是我想使用并行流的算法:

 @Override
    public Map<String, Double> getMapRealise(Date date, String code, Long pc) {
        Map<String, Double> map = new HashMap<>();
        List<Period> periodList = this.getListPeriod(date, code);
        Double realiseValeur = 0.0;
        Double invalidite = 0.0;
        if (periodList != null) {


            for (Period period : periodList) {
                Double periode = this.getResolutionTraduiteEnHeures(period.getResolution().getV());
                // Date dateDebutPrevisionnel =
                // this.getDateDebutPrevisionnel(period.getTimeInterval().getV());
                Double nbValid = 0.0;
                for (Pt pt : period.getListPt()) {
                    realiseValeur += periode * pt.getQ().getV() / pcnTranche / NBR_HEURES_PAR_JOURS;
                    nbValid = nbValid + pt.getCq().getV();
                }

                if ((nbValid * periode) < NBR_HEURES_MINE_PAR_JOURS) {
                    invalidite++;
                }
            }
        }

        else {
            LOGGER.warn(  "n existe pas ");
        }
        map.put(REALISE_VALEUR, realiseValeur);
        map.put(REALISE_INVALIDITE, invalidite);

        return map;}

I tried this but i got the error Local variable defined in an enclosing scope must be final for realiseValeur, nbValid and invalidite:我试过这个,但我得到了错误 Local variable defined in an enclosure scope must be final for realiseValeur, nbValid and invalidite:

@Override
    public Map<String, Double> getMapRealise(Date date, String code, Long pc) {
        Map<String, Double> map = new HashMap<>();
        List<Period> periodList = this.getListPeriod(date, code);
        Double realiseValeur = 0.0;
        Double invalidite = 0.0;
        if (periodList != null) {

            periodList.parallelStream().forEach(period -> {
                Double periode = this.getResolutionTraduiteEnHeures(period.getResolution().getV());
                // Date dateDebutPrevisionnel =
                // this.getDateDebutPrevisionnel(period.getTimeInterval().getV());
                Double nbValid = 0.0;
                period.getListPt().parallelStream().forEach(pt -> {
                    realiseValeur += periode * pt.getQ().getV() / pcnTranche / NBR_HEURES_PAR_JOURS;
                    nbValid = nbValid + pt.getCq().getV();
                });

                if ((nbValid * periode) < NBR_HEURES_MINE_PAR_JOURS) {
                    invalidite++;
                }
            });

        }

        else {
            LOGGER.warn("n existe pas ");
        }
        map.put(REALISE_VALEUR, realiseValeur);
        map.put(REALISE_INVALIDITE, invalidite);

        return map;
    }

You need to return something from each iteration of the outer loop which has the incremental values for each of the iterations.您需要从外部循环的每次迭代中返回一些内容,其中包含每次迭代的增量值。

Stream<Map<String, Double>> fromParallel =
    periodList.parallelStream()
        .map(period -> {
            double realiseValeurInc = 0.0;
            double invaliditeInc = 0.0;

            // Increment these variables instead of realiseValeur and invalidite

            return Map.of(REALISE_VALEUR, realiseValeurInc, REALISE_INVALIDITE, invaliditeInc);
        });

Now just merge all of these maps together:现在只需将所有这些地图合并在一起:

Map<String, Double> result =
    fromParallel.reduce(
        (a, b) -> Map.of(
            REALISE_VALEUR, a.get(REALISE_VALEUR) + b.get(REALISE_VALEUR),
            REALISE_INVALIDITE, a.get(REALISE_INVALIDITE) + b.get(REALISE_INVALIDITE)));

(You don't have to do this in two separate steps, that's merely to explain the process.) (您不必分两个单独的步骤执行此操作,这只是为了解释该过程。)

And you can use this as the return value (or copy this to a HashMap, if that's what you really need).您可以将其用作返回值(或将其复制到 HashMap,如果这是您真正需要的)。

Of course, this is wildly inefficient, because of all the allocation of both Double and Map .当然,这是非常低效的,因为DoubleMap的所有分配。 It will probably be slower than the existing loop-based code.它可能会比现有的基于循环的代码慢。 But it will at least give you the correct answer (eventually).但它至少会给你正确的答案(最终)。

You can use AtomicInteger for this operation.您可以使用 AtomicInteger 进行此操作。 since you are using Double for your opeartions.因为您使用 Double 进行操作。 create your own AtomicFloat and use it instead of Double and your problem will be solved:)创建您自己的 AtomicFloat 并使用它而不是 Double ,您的问题将得到解决:)

import java.util.concurrent.atomic.AtomicInteger;
import static java.lang.Float.*;

class AtomicFloat extends Number {

    private AtomicInteger bits;

    public AtomicFloat() {
        this(0f);
    }

    public AtomicFloat(float initialValue) {
        bits = new AtomicInteger(floatToIntBits(initialValue));
    }

    public final boolean compareAndSet(float expect, float update) {
        return bits.compareAndSet(floatToIntBits(expect),
                                  floatToIntBits(update));
    }

    public final void set(float newValue) {
        bits.set(floatToIntBits(newValue));
    }

    public final float get() {
        return intBitsToFloat(bits.get());
    }

    public float floatValue() {
        return get();
    }

    public final float getAndSet(float newValue) {
        return intBitsToFloat(bits.getAndSet(floatToIntBits(newValue)));
    }

    public final boolean weakCompareAndSet(float expect, float update) {
        return bits.weakCompareAndSet(floatToIntBits(expect),
                                      floatToIntBits(update));
    }

    public double doubleValue() { return (double) floatValue(); }
    public int intValue()       { return (int) get();           }
    public long longValue()     { return (long) get();          }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在封闭作用域中定义的局部变量必须是最终的或有效的最终变量 - Local variable defined in an enclosing scope must be final or effectively final 在封闭 scope 中定义的局部变量迭代必须是最终的或有效的最终 - local variable iteration defined in an enclosing scope must be final or effectively final 在封闭 scope 中定义的局部变量 ObjList 必须是最终的或有效的最终 - Local variable ObjList defined in an enclosing scope must be final or effectively final 在封闭范围内定义的局部变量 log 必须是 final 或有效 final - Local variable log defined in an enclosing scope must be final or effectively final 线程:封闭范围中定义的局部变量必须是final或有效的final - Threads: Local variable defined in an enclosing scope must be final or effectively final 我在封闭作用域中定义的局部变量必须是最终的或有效的最终变量 - Local variable i defined in an enclosing scope must be final or effectively final 获取在封闭 scope 中定义的局部变量必须是最终的或有效的最终 - Getting local variable defined in the enclosing scope must be final or effective final 封闭范围中定义的局部变量计数必须是最终错误 - Local variable count defined in an enclosing scope must be final error Java 8 显示此错误。 在封闭作用域中定义的局部变量 itemList 必须是 final 或有效 final - Java 8 shows this error. Local variable itemList defined in an enclosing scope must be final or effectively final Java 定时器:在封闭 scope 中定义的局部变量计数必须是最终的或有效的最终 - Java Timer: local variable count defined in an enclosing scope must be final or effectively final
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM