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"));