我在Java 7循环和Java 8 forEach循环中迭代数组列表.Java 8循环希望循环内的变量是最终的.例如,
List<String> testList = Arrays.asList( "apple", "banana", "cat", "dog" );
int count = 0;
testList.forEach(test -> {
count++; // Compilation error: Local variable count defined in an enclosing scope must be final or effectively final
});
for (String test : testList) {
count++; // Code runs fine
}
Run Code Online (Sandbox Code Playgroud)
有人可以解释为什么会这样吗?这是Java 8的缺点吗?
我正在玩Java 8并且遇到了一个基本场景,它说明了修复一个编译错误导致另一个编译错误的问题22.场景(这只是一个从更复杂的东西中简化的例子):
public static List<String> catch22(List<String> input) {
List<String> result = null;
if (input != null) {
result = new ArrayList<>(input.size());
input.forEach(e -> result.add(e)); // compile error here
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我收到编译错误:
在封闭范围内定义的局部变量结果必须是最终的或有效的最终结果
如果我将第一行更改为:
List<String> result;
Run Code Online (Sandbox Code Playgroud)
我在最后一行收到编译错误:
局部变量结果可能尚未初始化
似乎这里唯一的方法是将我的结果预初始化为ArrayList,我不想这样做,或者不使用lambda表达式.我错过了任何其他解决方案吗?
我有以下课程:
public class Item{
private String name;
//setter getter
}
Run Code Online (Sandbox Code Playgroud)
和物品的集合.我想得到Collection中最后一项的名字.要做到这一点,我只需迭代所有集合并使用最后.问题是我不知道为什么它迫使我使用一个元素String数组.
为什么我必须使用:
String[] lastName = {""};
items.forEach(item -> lastName[0] = item.getName());
System.out.println(lastname[0]);
Run Code Online (Sandbox Code Playgroud)
代替:
final String lastName;
items.forEach(item -> lastName = item.getName());
System.out.println(lastname);
Run Code Online (Sandbox Code Playgroud) 我偶然发现了这个技巧,从匿名内部类中获取一个值,该变量在外部类中声明.它有效,但感觉就像一个肮脏的黑客:
private int showDialog()
{
final int[] myValue = new int[1];
JPanel panel = new JPanel();
final JDialog dialog = new JDialog(mainWindow, "Hit the button", true);
dialog.setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE );
JButton button = new JButton("Hit me!");
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
myValue[0] = 42;
dialog.setVisible(false);
}
});
panel.add(button);
dialog.add(panel);
dialog.pack();
dialog.setVisible(true);
return myValue[0];
}
Run Code Online (Sandbox Code Playgroud)
(是的,我意识到这个例子可以用一个简单的替换JOptionPane,但我的实际对话框要复杂得多.)内部函数坚持认为它与之交互的所有变量都是final,但我不能将其声明myValue为final,因为内部函数需要为其分配一个值.将它声明为1元素阵列解决了这个问题,但似乎它可能是某种坏事TM.我想知道是否a.)这是常见做法或b.)这可能导致任何严重问题.
有没有办法将以下代码转换为Java 8 Stream.
final List ret = new ArrayList(values.size());
double tmp = startPrice;
for (final Iterator it = values.iterator(); it.hasNext();) {
final DiscountValue discountValue = ((DiscountValue) it.next()).apply(quantity, tmp, digits, currencyIsoCode);
tmp -= discountValue.getAppliedValue();
ret.add(discountValue);
}
Run Code Online (Sandbox Code Playgroud)
Java 8流抱怨没有最终变量tmp?有办法解决这种情况吗?
在封闭范围内定义的局部变量tmp必须是最终的或有效的最终