Java 8-如何将属性值从一个列表复制到另一个列表?

Java 8-如何将属性值从一个列表复制到另一个列表?,java,lambda,java-8,Java,Lambda,Java 8,我有两个列表,例如: List<Foo> list1 = Lists.newArrayList(new Foo(...),...); List<Bar> list2 = Lists.newArrayList(new Bar(...),...); 但编译失败了 在封闭范围中定义的局部变量索引必须是final或final Java 8是否有一些方便的方式来处理这个问题?您不能从lambda表达式内部修改索引变量 您可以使用IntStream迭代索引(尽管与简单的for循环相

我有两个
列表,例如:

List<Foo> list1 = Lists.newArrayList(new Foo(...),...);
List<Bar> list2 = Lists.newArrayList(new Bar(...),...);
但编译失败了

在封闭范围中定义的局部变量索引必须是final或final


Java 8是否有一些方便的方式来处理这个问题?

您不能从lambda表达式内部修改
索引
变量

您可以使用
IntStream
迭代索引(尽管与简单的for循环相比,这并没有多大改进):

你可以做:

IntStream.range(0, list1.size())
         .forEach(i -> list2.get(i).fooId = list1.get(i).getId());
但请注意,这不是一个好的函数代码。最好为
循环编写一个显式的
,而不要使用流

您问题中的代码不起作用,因为您不能在lambda表达式中引用非final(或实际上是final)的变量

如果您不介意此操作后的
list1
,并且可以删除它的元素,您也可以使用以下方法:

list2.forEach(bar -> bar.fooId = list1.remove(0).getId());

不幸的是,Java8StreamsAPI中没有zip操作。但你们可以使用图书馆

List upd=StreamUtils.zip(list1.stream(),list2.stream(),(foo,bar)->{
setId(foo.getId());
返回杆;
}).collect(Collectors.toList());
我还想补充一点,使用可变数据对象是一种必要的风格。在函数式中,如果需要更改任何内容,最好使用不可变数据并返回新对象。

使用“我的库”,可以简化样板文件:

EntryStream.zip(list1, list2).forKeyValue((foo, bar) -> bar.fooId = foo.getId());
为每个对应的
list1
list2
对创建
Map.Entry
流。该方法接受
BiConsumer
(它是
forEach
的语法糖)。在内部,它接近@Eran解决方案

list2.forEach(bar -> bar.fooId = list1.remove(0).getId());
List<Bar> upd = StreamUtils.zip(list1.stream(), list2.stream(), (foo, bar) -> {
  bar.setId(foo.getId());
  return bar;
}).collect(Collectors.toList());
EntryStream.zip(list1, list2).forKeyValue((foo, bar) -> bar.fooId = foo.getId());