ner*_*sol 7 java lambda java-8
我有以下课程:
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)
tob*_*s_k 13
你不能创建lastName一个String,因为在lambda(或匿名内部类)中使用的局部变量必须(有效地)final(见这里),即你不能在.forEach循环中每次执行lambda时覆盖它.使用数组(或其他一些包装器对象)时,不要为该变量赋值,而只是更改它的某些方面,因此它可以是最终的.
或者,您可以使用reduce跳到最后一项:
String lastName = items.stream().reduce((a, b) -> b).get().getName();
Run Code Online (Sandbox Code Playgroud)
或者,如评论中skip所述,首先是n-1个元素,然后是第一个:
String last = items.stream().skip(items.size() - 1).findFirst().get().getName();
Run Code Online (Sandbox Code Playgroud)
final实际上意味着您必须分配一次(并且只有一次,编译时分析保证)。例如,以下代码无效:
final String lastName;
List<Item> items = new ArrayList<Item>();
items.add(new Item("only one element"));
for (Item item:items) lastName = item.getName();
Run Code Online (Sandbox Code Playgroud)
在您的第二个 lambda 表达式中,消费者分配给lastName,已声明为final:
final String lastName;
items.forEach(item -> lastName = item.getName());
Run Code Online (Sandbox Code Playgroud)
由于在 lambda 表达式中引用的变量必须是有效的最终变量(即可以将final关键字添加到其定义中),删除final声明中的关键字lastName无济于事:这里lastName实际上是最终的,并且消费者分配给有效的最终多变的。
String lastName;
items.forEach(item -> lastName = item.getName());
Run Code Online (Sandbox Code Playgroud)
另一方面,在您的第一个表达式中,有效的最终变量是lastName,它是一个数组。然后你可以这样做:
String[] lastName = {""};
items.forEach(item -> lastName[0] = item.getName());
Run Code Online (Sandbox Code Playgroud)
因为在这里您没有分配给有效的最终变量,而只是修改其元素(请记住,常量是引用,而不是其值),如下例中的情况也是如此:
final String[] lastName = new String[1];
lastName[0]="foo";
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3852 次 |
| 最近记录: |