我有一个Set<Person>,我需要过滤内容,然后填充给定集合中的另一个集合.

我对streams还是个新手.

我能想到的第一个解决方案是链接stream().filter().foreach()

Solution 1:

private Set<Person> mapPerson(final Set<Student> student) {
        final Set<Person> person = new HashSet<>();
        student.stream()
            .filter(student1 -> Objects.nonNull(student.getAge()))
            .forEach(student1 -> person.add(Person.builder()
                .id(student1.getId())
                .status(student1.getStatus()))
                .build()));

        return person;
    }

但我不确定这是否可以通过链接stream().filter().map()来实现?

非常感谢您的帮助,如果两种方法都可以,您更喜欢哪种方法?

推荐答案

为此,您不需要手动创建一个集合,然后对其进行变异.您可以通过执行流管道获得一个集合.

可以通过链接stream().filter().map()来实现吗?

首先,通过应用map()操作将学生流Stream<Student>转换为人物对象流Stream<Person>,该操作期望一个函数将流的元素转换为所需类型的另一个对象.所以你需要把创建Person对象的逻辑放在forEach()map()中.

然后应用collect作为参数Collectors.toSet().

private Set<Person> mapPerson(final Set<Student> students) {

  return students.stream()
          .filter(student -> Objects.nonNull(student.getAge()))
          .map(student -> Person.builder()
                          .id(student.getId())
                          .status(student.getStatus())
                          .build())
          .collect(Collectors.toSet());
}

如果两种方法都有可能,那么哪种方法更可取?

你使用的方法是discourageddocumentation.看看下面的引文(emphasize is mine).

作为如何转换流管道的示例

 ArrayList<String> results = new ArrayList<>();
 stream.filter(s -> pattern.matcher(s).matches())
       .forEach(s -> results.add(s));  // Unnecessary use of side-effects!

... forEach()可以简单地替换为一个还原操作

 List<String> results =
     stream.filter(s -> pattern.matcher(s).matches())
           .toList();  // No side-effects!

你不应该使用forEach(以及peek),因为只有在有其他方法达到相同效果的情况下,forEach才能产生副作用.

在这种情况下,可以使用collect()(as shown above)或普通for循环.

Java相关问答推荐

我们如何直接使用kerminldap服务票证来通过ldap进行身份验证并形成LDAP上下文

在Java中测试DAO方法:假实现与内存数据库

为什么在枚举中分支预测比函数调用快?

如何找到MongoDB文档并进行本地化?

使用Spring Boot3.2和虚拟线程的并行服务调用

按属性值从流中筛选出重复项

声明MessageChannel Bean的首选方式

如何只修改父类ChroniclerView位置0处的第一个嵌套ChroniclerView(child)元素?

Domino Designer 14中的保存代理添加了重影库

%This内置函数示例

如何将Java文档配置为在指定的项目根目录中生成?

JNI:将代码打包成自包含的二进制文件

如何在太阳系模拟器中添加月球?

来自外部模块的方面(对于Java+Gradle项目)不起作用

将ByteBuffer异步写入InputStream或Channel或类似对象

在Spring Boot应用程序中,server.port=0的默认端口范围是多少?

如何在运行docker的应用程序中获取指定的配置文件

如何使用jooq更新记录?

在权限列表中找不到我的应用程序

如何将RESTAssured';S的Http标题转换为<;字符串、字符串和>的映射?