Java 迭代CustomObject列表,使用条件过滤并设置特定属性
我有以下提到的过滤器和设置器的问题 我有一个自定义类Java 迭代CustomObject列表,使用条件过滤并设置特定属性,java,java-stream,Java,Java Stream,我有以下提到的过滤器和设置器的问题 我有一个自定义类A,还有一个as列表。 我想用a1=“a2”条件迭代列表和筛选,并想用我的自定义消息设置a2属性。 我能够使用Java 8的流、过滤、映射和收集功能。 我也提到了同样的代码 list.stream().filter(a->a.getA1().equalsIgnoreCase(“a2”)).map(a->a.toBuilder().a2(“新a2值”).collect(Collectors.toList()) 当我试图再次打印同一个列表,但该属性
A
,还有一个as列表。
我想用a1=“a2”
条件迭代列表和筛选,并想用我的自定义消息设置a2
属性。
我能够使用Java 8的流、过滤、映射和收集功能。
我也提到了同样的代码
list.stream().filter(a->a.getA1().equalsIgnoreCase(“a2”)).map(a->a.toBuilder().a2(“新a2值”).collect(Collectors.toList())代码>
当我试图再次打印同一个列表,但该属性没有更新时
同样,当我用列表分配这个表达式并尝试打印它时,它会给我1条经过过滤的记录和更新的值。但它并没有更新我的实际名单
谁能给我指路吗
@Builder(toBuilder = true)
@Data
class A {
String a1;
String a2;
String a3;
A(String b1, String b2, String b3) {
this.a1 = b1;
this.a2 = b2;
this.a3 = b3;
}
}
class Main {
public static void main(String[] args) {
A obj1 = new A("a1", "b1", "b1");
A obj2 = new A("a2", "b2", "b2");
A obj3 = new A("a3", "b3", "b3");
A obj4 = new A("a2", "b4", "b4");
A obj5 = new A("a2", "b5", "b5");
var list= new ArrayList<A>();
list.add(obj1);
list.add(obj2);
list.add(obj3);
list.add(obj4);
list.add(obj5);
list.stream().filter(a -> a.getA1().equalsIgnoreCase("a2"))
.map(a -> a.toBuilder()
.a2("New a2 value"))
.collect(Collectors.toList());
}
}
toBuilder()创建一个新实例。因此,当您访问Collectors.toList()时,将在新列表中获得一个新项
除非对原始元素执行.setA2(),否则无法更新这样的列表
// You can reuse the list then.
list.stream().filter(a -> a.getA1().equalsIgnoreCase("a2"))
.forEach(a -> {
a.setA2("New a2 value");
});
// Alternatively, use a method reference
list.stream().filter(a -> a.getA1().equalsIgnoreCase("a2"))
.map(a -> {
this::update
});
private A update(A a) {
a.setA2("new a2 value");
return a;
}
此外,不要感到被迫使用流。您还可以使用带有if()的for()循环。您需要将新创建的列表分配给一个变量,该变量可以与以前使用的相同,但它将是一个新的列表,并引入这些更改
要将其分配给同一个变量,只需在如下表达式之前添加list=
list = list.stream().filter(a -> a.getA1().equalsIgnoreCase("a2"))
.map(a -> a.toBuilder()
.a2("New a2 value"))
.collect(Collectors.toList());
我已经尝试过了,我能够在那里得到一个记录列表。但我的要求是只更新匹配记录的值
我不确定匹配记录的值是指更新列表还是保留列表中的元素并更新这些元素中的值。要更新元素的值,可以执行以下操作
list.stream()
.filter(a -> a.getA1().equalsIgnoreCase("a2"))
.forEach(a -> a.setA2("New a2 value"));
在这里,您没有创建新列表,只是更新通过过滤器的元素的值。流操作不会修改您的输入列表。您需要将结果分配给某个变量。在您的示例中,您只需忽略结果。@Amongalen,因为我在迭代和设置更新值时使用相同的引用。所以它应该在我的实际列表中更新。你认为哪个操作会修改对象?我不认为Lomboks builder会修改对象,而是创建一个新的对象。不一样a.toBuilder().a2(“新的a2值”)
如果我不使用lambda表达式,代码就可以正常工作。您在注释中发布的代码片段返回的对象类型是a.ABuilder
,而不是a
。它不修改a
对象。当我执行a.setA2()时,它要求我丢失返回值;如果我将返回a
本身,我的循环将到达那里,它将无法对我已经尝试过的其他元素执行此比较,并且我能够在那里获得筛选记录列表。但我的要求是只更新匹配记录的值。为什么要使用生成器?是否需要实例化新的a
?toBuilder()
的工作方式不同。唯一的要求是我只想更新匹配记录的值。
list.stream()
.filter(a -> a.getA1().equalsIgnoreCase("a2"))
.forEach(a -> a.setA2("New a2 value"));