Java Stream unique() 与其他修改流元素的链式操作会生成重复的结果

问题描述 投票:0回答:1

我正在使用 Java

Stream
distinct()
测试一些东西,我遇到了一个场景,如果我在执行
Stream
后更改
distinct()
的对象,则执行的最终结果包含重复的项目。

distinct()
最终确定之前,对象进入下一个操作是否有意义?如何在不迭代整个列表的情况下保证唯一性?

OBS:Lombok:

@Data
注释在Dto类中添加了
@EqualsAndHashCode
,它将自动生成
equals()
hashCode()
方法!

package br.com.marcusvoltolim;

import lombok.AllArgsConstructor;
import lombok.Data;
import reactor.core.publisher.Flux;

import java.util.*;
import java.util.stream.Collectors;

@Data
@AllArgsConstructor
class Dto {

    private Long id;

}

public class Main {

    public static void main(String[] args) {
        Dto dto0 = new Dto(0L);
        Dto dto1 = new Dto(1L);
        Dto dto2 = new Dto(1L);

        List<Dto> list = Arrays.asList(dto0, dto1, dto2);

        System.out.println("Original list: " + list);
        System.out.println("List with only distinct: " + list.stream().distinct().collect(Collectors.toList()));

        List<Dto> streamList = list.stream()
            .distinct()
            .map(dto -> {
                if (dto.getId() == 1L) {
                    dto.setId(3L);
                }
                return dto;
            })
            .collect(Collectors.toList());

        System.out.println("Java Stream  with map after distinct: " + streamList);
    }

}

结果:

Original list: [Dto(id=0), Dto(id=1), Dto(id=1)]
List with only distinct: [Dto(id=0), Dto(id=1)]
Java Stream with map after distinct: [Dto(id=0), Dto(id=3), Dto(id=3)]

我期待的结果:

[Dto(id=0), Dto(id=3)]

java java-stream
1个回答
5
投票

要获得“预期”行为,您无法更改列表中列表元素的值。

你有:

if (dto.getId() == 1L) {
    dto.setId(3L); // <--- Changing the contents
}

所以你正在改变节点的值和“等于”。

为了让它正常工作,你必须真正映射而不是修改:

if (dto.getId() == 1L) {
    return new Dto(3L); // <--- Map to new object
} else {
    return new Dto(dto.getId()); // <--- Map to new object
}
© www.soinside.com 2019 - 2024. All rights reserved.