从java8中的另一个列表lambda表达式更新对象列表



我有两个对象列表。对象是简单的类,包含键、值属性。我想从第二个列表更新第一个列表的值。替换或克隆列表不起作用,因为这两个列表的顺序不同,它们应该保持在各自的顺序中。任何建议。

示例:

for(int i = 0 ; i < mValues.size() ; i++)
{
for (int j = 0 ; j < mValues.size() ; j++)
{
if(newData.get(i).getKey().equalsIgnoreCase(mValues.get(j).getKey()))
{
mValues.get(j).setValue(newData.get(i).getValue());
}
}
}

演示:

myObject o1 = new myObject("k1" , 10);
myObject o2 = new myObject("k2" , 20);
myObject o3 = new myObject("k2" , 30);
myObject o4 = new myObject("k1" , 40);
List<myObject> l1 = new ArrayList<>();
List<myObject> l2 = new ArrayList<>();
l1.add(o1);
l1.add(o2);
l2.add(o3);
l2.add(o4);

这里应该通过查找密钥和更新值,在l2的基础上对l1进行更新。结果应该是:

l1 key is "k1" and value is 40 and next key is "k2" and the value is 30

我会为该作业使用流。

假设您的类MyObject定义了getters和setters方法(getKey()getValue()setKey()setValue()(,则可以执行:

l1.forEach(myObject1 -> l2.stream()
.filter(myObject2 -> myObject1.getKey().equals(myObject2.getKey()))
.findAny().ifPresent(myObject2 -> myObject1.setValue(myObject2.getValue())));

如果您可以有重复的密钥,那么您应该将ifPresent()修改为forEach():

l1.forEach(myObject1 -> l2.stream()
.filter(myObject2 -> myObject1.getKey().equals(myObject2.getKey()))
.forEach(myObject2 -> myObject1.setValue(myObject2.getValue())));

我想不出多少优雅的单行流。我的建议分为两步:

  1. l2转换为map
  2. CCD_ 9中的流映射改变项。这是一个更灵活、更易于调试的解决方案
static class myObject {
String key;
int val;
public myObject(String key, int val) {
this.key = key;
this.val = val;
}
@Override
public String toString() {
return "myObject{" +
"key='" + key + ''' +
", val=" + val +
'}';
}
}
public static void main(String[] args) {
myObject a = new myObject("k1", 30);
myObject b = new myObject("k2", 40);
Map<String, myObject> list2map = List.of(a,b).stream().collect(Collectors.toMap(m -> m.key, m -> m));
myObject c = new myObject("k1", 10);
myObject d = new myObject("k2", 20);
List<myObject> l1 = List.of(c, d);
l1 = l1.stream().map(m -> {
m.val = list2map.getOrDefault(m.key, m).val;
return m;
}).collect(Collectors.toList());
System.out.println(l1);
}

最新更新