How to use non final variable in Java 8 Lambdas

2020-08-11 04:14发布

问题:

How can I use non-final variable in Java 8 lambda. It throws compilation error saying 'Local variable date defined in an enclosing scope must be final or effectively final'

I actually want to achieve the following

public Integer getTotal(Date date1, Date date2) {
    if(date2 == null || a few more conditions) {
        date2 = someOtherDate;
    }
    return someList.stream().filter(filter based on date1 and date2).map(Mapping Function).reduce(Addition);
}

How do I achieve this? It throws comilation error for date2. Thanks,

回答1:

Use another variable that you can initiate once.

final Date tmpDate;
if(date2 == null || a few more conditions) {
    tmpDate = someOtherDate;
} else {
    tmpDate = date2;
}


回答2:

This should be helpful.

public Long getTotal(Date date1, Date date2) {
    final AtomicReference<Date> date3 = new AtomicReference<>();
    if(date2 == null ) {
        date3.getAndSet(Calendar.getInstance().getTime());
    }
    return someList.stream().filter(x -> date1.equals(date3.get())).count();
}


回答3:

I think you should just get the param date2 outside and then calling the method getTotal, just like this below:

Date date1;
Date date2;

if(date2 == null || a few more conditions) {
   date2 = someOtherDate;
}

getTotal(date1, date2)


public Integer getTotal(Date date1, Date date2) {
    return someList.stream().filter(filter based on date1 and date2).map(Mapping Function).reduce(Addition);
}


回答4:

Just add a line like

Date date3 = date2; // date3 is effectively final in Java 8. Add 'final' keyword in Java 7.

right before your lambda and use date3 in place of date2.