如何在Java8流/过滤器中使用非final变量? [英] How to use non-final variable inside Java8 streams/filters?

查看:559
本文介绍了如何在Java8流/过滤器中使用非final变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的用例中,我想更新变量的值,并在流的下一次迭代中引用它。

In my use case I would like to update the value of a variable and reference the same in next iteration in streams.

但是java编译器给了我错误。这是我的代码

But the java compiler is giving me error. Here is my code

static String convertList(        
  List<Map.Entry<String, String>> map,         
  String delimiter,            
  long maxLength        
) {          
    long currentLength = 0L;          
    return map.stream()
    .map(e->e.getKey() + "=" + e.getValue())        
    .filter(p->{                
      long pLength = p.getBytes(StandardCharsets.UTF_8).length;        
      currentLength = currentLength + pLength;        
      if (currentLength <= maxLength) {         
        return true;        
      } else {
        return false;        
      }
    })
  .collect(Collectors.joining(delimiter));        
}

我试图将列表中的值变为字符串,直到长度为止[直到这次迭代]< = maxlength

I am trying to get the values from the list to a string until the length [till this iteration] <= maxlength

有人可以帮我解决这个问题吗?我得到从lambda表达式引用的局部变量必须是final或者有效的最终错误。

could someone help me fix this? I am getting Local variables referenced from a lambda expression must be final or effectively final error.

推荐答案

你的变量必须是最终/有效的最终才能在lambda中使用它。您仍然可以通过使用类似数组的最终容器对象来实现目标 - 特别是对于您的示例, long [1] AtomicLong 会运作良好 - 参考是最终的,但您可以更改内容。

Your variable must be final / effectively final to use it inside lambda. You can still accomplish your goal by using a final 'container object' like an array - specifically for your example, long[1] or AtomicLong would work well - the reference is final, but you can change out the contents.

根据您的代码示例:

final long[] currentLength = new long[1];          
return map.stream()
    .map(e->e.getKey() + "=" + e.getValue())        
    .filter(p->{                
        long pLength = p.getBytes(StandardCharsets.UTF_8).length;        
        currentLength[0] = currentLength[0] + pLength;        
        if (currentLength[0] + maxLength <= maxLength) {         
            return true;        
        } else {
            return false;        
        }
    }).collect(Collectors.joining(delimiter));

注意,您还可以按如下方式简化过滤器:

Note, you can also simplify your filter as follows:

    .filter(p->{                
        long pLength = p.getBytes(StandardCharsets.UTF_8).length;        
        currentLength[0] = currentLength[0] + pLength;        
        return (currentLength[0] + maxLength <= maxLength);
    })

这篇关于如何在Java8流/过滤器中使用非final变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆