Java8显示了这个错误。在封闭范围中定义的局部变量itemList必须是final或final

Java8显示了这个错误。在封闭范围中定义的局部变量itemList必须是final或final,java,java-8,java-stream,Java,Java 8,Java Stream,我正在使用Java8编写代码,但我迭代了一个列表,然后使用category type查找RestaurantOrderBook。并将该列表放入地图。它显示了这个错误: 在封闭范围中定义的局部变量itemList必须是final或有效final Query Query=new Query(); 字符串类别=类别; query.addCriteria(Criteria.where(“restaurantId”).is(restaurantId)); List itemList=new ArrayLi

我正在使用Java8编写代码,但我迭代了一个
列表
,然后使用category type查找
RestaurantOrderBook
。并将该
列表
放入
地图
。它显示了这个错误:

在封闭范围中定义的局部变量itemList必须是final或有效final

Query Query=new Query();
字符串类别=类别;
query.addCriteria(Criteria.where(“restaurantId”).is(restaurantId));
List itemList=new ArrayList();
itemList=mongoTemplate.find(查询,RestaurantOrderBook.class);
System.out.println(“大小:+itemList.size());
Map Map=newhashmap();
Arrays.asList(“外卖”、“餐饮”).forEach(e->{
//以下行抛出错误:
List List=itemList.stream();
地图放置(e,列表);
});
我有另一种情况:

@Override
    public EventReportRewardsPoints eventReportRewardsPoints(String organizerId) {
        try{
            List<Event> listOfEvents = eventRepo.findByOrganizerId(organizerId);
            EventReportRewardsPoints eventTransReport = new EventReportRewardsPoints();
            Integer soldTics = 0;
            Double totalRevenue = 0d;
            Integer soldToday  = 0;

            Integer findTotalAvailableTics = 0;
            Integer findTotalQtytics = 0;

            for (Event event : listOfEvents) {
                List<EventTicket> eventTicket = eventTicketRepo.findByEventId(event.getId());

                Integer sumOfAvailabletics = eventTicket.stream()
                        .mapToInt(EventTicket::getRemainingTickets).sum();
                findTotalAvailableTics = findTotalAvailableTics + sumOfAvailabletics;

                Integer sumOfQtytics = eventTicket.stream().mapToInt(EventTicket::getQty).sum();
                findTotalQtytics  = findTotalQtytics + sumOfQtytics;

                List<EventTicketBook> listOfEventsTic = eventTicketBookRepository.findByEventId(event.getId());
                for (EventTicketBook eventTicketBook : listOfEventsTic) {
                    Double sumOfSales = eventTicketBook.getTickets().stream().mapToDouble(EventTicket::getPrice).sum();
                    totalRevenue = totalRevenue + sumOfSales;
                    Date now = new Date();
                    System.out.println("create date : " + eventTicketBook.getCreateOn());
                    /*if(now.compareTo(eventTicketBook.getCreateOn()) == 0){
                        Integer sumOfSoldToday = eventTicketBook.getTickets().stream().mapToInt(EventTicket::getQty).sum();
                        soldToday = soldToday + sumOfSoldToday;
                    }*/
                }
            }
            System.out.println("findTotalQtytics : " + findTotalQtytics);
            System.out.println("findTotalAvailableTics : " + findTotalAvailableTics);
            soldTics = findTotalQtytics - findTotalAvailableTics;
            eventTransReport.setTotalRevenue(totalRevenue);
            eventTransReport.setSoldToday(soldToday);
            eventTransReport.setTicketsSold(soldTics);
            return eventTransReport;
        }catch(Exception e ){
            e.printStackTrace();
        }
        return null;
    }
@覆盖
公共事件报告RewardsPoints事件报告RewardsPoints(字符串organizerId){
试一试{
List ListoEvents=eventRepo.FindByorOrganizerId(organizerId);
EventReportRewardsPoints eventTransReport=新的EventReportRewardsPoints();
整数soldTics=0;
双倍总收入=0d;
整数soldToday=0;
整数findTotalAvailableTics=0;
整数findTotalQtytics=0;
for(事件:listOfEvents){
List eventTicket=eventticketropo.findByEventId(event.getId());
整数sumOfAvailabletics=eventTicket.stream()
.mapToInt(EventTicket::getRemainingTickets).sum();
findTotalAvailableTics=findTotalAvailableTics+可用性总和;
整数sumOfQtytics=eventTicket.stream().mapToInt(eventTicket::getQty.sum();
findTotalQtytics=findTotalQtytics+sumOfQtytics;
List listOfEventsTic=eventTicketBookRepository.findByEventId(event.getId());
对于(事件票证簿事件票证簿:listOfEventsTic){
Double-sumOfSales=eventTicketBook.getTickets().stream().mapToDouble(EventTicket::getPrice.sum();
总收入=总收入+销售总额;
现在日期=新日期();
System.out.println(“创建日期:+eventTicketBook.getCreateOn());
/*if(now.compareTo(eventTicketBook.getCreateOn())==0){
整数sumOfSoldToday=eventTicketBook.getTickets().stream().mapToInt(EventTicket::getQty.sum();
soldToday=soldToday+sumOfSoldToday;
}*/
}
}
System.out.println(“findTotalQtytics:+findTotalQtytics”);
System.out.println(“findtotalavabletics:+findtotalavabletics”);
soldTics=findTotalQtytics-findTotalAvailableTics;
eventTransReport.setTotalRevenue(totalRevenue);
eventTransReport.setSoldToday(soldToday);
eventTransReport.setticketssell(soldTics);
返回事件报告;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}

如何使用lamda表达式实现此目的。??

声明变量itemList final:

final List<RestaurantOrderBook> itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
final List itemList=mongoTemplate.find(查询,RestaurantOrderBook.class);

您正在lambda表达式中使用itemList。因此,它必须是最终的

Java8引入了有效final的新概念,这意味着编译器会检查所使用的变量是否为final,并且不会强制开发人员显式地将其声明为final

因此,如果您将代码更改为

final List<RestaurantOrderBook> itemList = new ArrayList<RestaurantOrderBook>();
因为您正在重新设计项目列表。这就是为什么itemList也不是有效的最终版本。如果你把这两行挤到一起

List<RestaurantOrderBook> itemList = mongoTemplate.find(query, RestaurantOrderBook.class);
List itemList=mongoTemplate.find(查询,RestaurantOrderBook.class);

它应该有效。

正如wumpz的公认答案所指出的,原因是所使用的变量必须是最终变量或有效的最终变量

我想补充一下原因来解释为什么会这样:

当我们编写Lambda表达式时,我们实际上是在编写一个匿名内部类。例如:

@FunctionalInterface
interface MyInterface{
    public void print();
}
在我们的代码中用作:

public static void main(String[] args) {
        int i = 6;  

        new MyInterface() {             
            @Override
            public void print() {                
                System.out.println(++i); // Remove ++ to resolve error
            }
        }.print();
    }

可能的副本我已经阅读了stackover flow中的帖子,但我无法理解。请用一种简单的方式解释我,我很好奇,为什么这会被否决,因为这是Java8Lambda/streams领域的一个常见问题。还是因为重复?@Navanethan Arun请提出一个新问题,而不是用第二个问题来强化原来的问题one@StefanZobel我想把我的第二种情况改成lamda。请转换代码或给我你自己的想法。谢谢你为我度过的黄金时光。这是宣布最终结果的好方法吗?也许我将来会在列表中添加一些记录。我该怎么办?没必要。最后,编译器有效地检查使用情况。因此,此答案只在正确的位置提供错误消息。使用final关键字,您仍然可以将项添加到列表中,但不能将其他列表分配给变量itemList。这是正确的,但lambda表达式中的用法不必如此,因为编译器将为您检查它(实际上是final).以后我可以再添加一些记录吗?因为它是最终的。是的。final的意思只是,您不能将itemList设置为另一个列表实例,但这并不意味着您的列表实例本身是只读的。如何将代码编写为lamda。?当我写它时,它给出了相同的错误。“本地变量b
@FunctionalInterface
interface MyInterface{
    public void print();
}
public static void main(String[] args) {
        int i = 6;  

        new MyInterface() {             
            @Override
            public void print() {                
                System.out.println(++i); // Remove ++ to resolve error
            }
        }.print();
    }