【问题标题】:Converting Stream into IntStream将 Stream 转换为 IntStream
【发布时间】:2023-03-11 23:01:01
【问题描述】:

我正在为两个列表的主地址相等的每个列表项设置 ID。

服务器 POJO

public class Server {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id")
    public Integer id;


    @OneToMany (mappedBy = "server",cascade = CascadeType.ALL, orphanRemoval = true)
    private List<IPAddress> ipaddresses;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }


    public void setIpaddresses(List<IPAddress> ipaddresses) {
        this.ipaddresses = ipaddresses;
    }

    public List<IPAddress> getIpaddresses() {
        return ipaddresses;
    }
}

IP 地址 POJO

public class IPAddress {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="ID")
    public Integer id;

    @Column(name="ipaddress")
    private String ipaddress;

    @Column(name="primaryIP")
    private boolean primary;

    @ManyToOne
    @JsonIgnore
    @JoinColumn(name = "server_id")
    private Server server;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getIpaddress() {
        return ipaddress;
    }

    public void setIpaddress(String ipaddress) {
        this.ipaddress = ipaddress;
    }

    public boolean isPrimary() {
        return primary;
    }

    public void setPrimary(boolean primary) {
        this.primary = primary;
    }

    public Server getServer() {
        return server;
    }

    public void setServer(Server server) {
        this.server = server;
    }


}

这是我替换重复项的逻辑。

注意: currServerList 是来自 db 和 importServerList 的列表,我将服务器导入 db,因此 importServerList 在我替换 currServerList 时将没有 id 我想更新服务器(替换为 importServerList)而不是重复。

Set<String> primaryIpAddresses = importServerList.stream()
                    .map(Server::getPrimaryIpAddress)
                    .collect(Collectors.toSet());

            Set<Integer> currServerId = currServerList.stream()
                    .filter(s->primaryIpAddresses.contains(s.getPrimaryIpAddress()))
                    .map(Server::getId)
                    .collect(Collectors.toSet());

            List<Server> filteredList=currServerList.stream()
                    .filter(s->!primaryIpAddresses.contains(s.getPrimaryIpAddress()))
                    .collect(Collectors.toList());
            filteredList.addAll(importServerList);
            filteredList.stream().filter(s->primaryIpAddresses.contains(s.getPrimaryIpAddress())).forEach(s->s.setId(currServerList.stream().filter(server->currServerId.contains(server.getId())).mapToInt(Server::getId)));

这是我的逻辑,但是我尝试过如何将此 Stream 转换为 IntStream 但不工作 filteredList.stream().filter(s->primaryIpAddresses.contains(s.getPrimaryIpAddress())).forEach(s->s.setId(currServerList.stream().filter(server->currServerId.contains( server.getId())).mapToInt(Server::getId))); 编译器错误:类型Server中的setId(Integer)方法不适用于参数(IntStream)

仍然无法工作,因为我没有将 id 设置为相等

更新:

filteredList.stream().filter(s->currListPrimaryIpAddress.contains(s.getPrimaryIpAddress()))
            .forEach(srv -> srv.setId(currServerList.stream().filter(server->primaryIpAddresses.contains(server.getPrimaryIpAddress()))
            .findFirst()
            .get().getId())); 

答案中的先前代码为所有服务器设置相同的 id,但我尝试使用类似这样的简单 for-each 循环而不进行函数式编程

for(Server srv : filteredList) {
                for(Server dbsrv : currServerList) {
                    logger.debug("dbsrv ipadd --> " + dbsrv.getPrimaryIpAddress());
                    logger.debug("impsrv ipadd --> " + srv.getPrimaryIpAddress());
                    if(dbsrv.getPrimaryIpAddress()!= null && dbsrv.getPrimaryIpAddress().equals(srv.getPrimaryIpAddress())) {
                        srv.setId(dbsrv.getId());
                        logger.debug("in setting server id");
                        break;
                    }
                }
            }

现在检查 null 是必要的,因为它在该行抛出异常,因为 db 中有一些数据是错误的,因此我正在做 防御性编码,但现在我需要在上面编写相同的内容使用函数式编程的代码。

【问题讨论】:

  • 不确定这条线IntStream.currServerList.stream().这可能吗?
  • @manfromnowhere 在我这样使用时无法正常工作.....你有我的问题吗?
  • 当我基于主 ipaddress 等于 importServerList 的服务器从 currServerList 替换服务器时,我需要将 currServerList 的替换服务器的 ID 设置到 importServerList 中
  • 有一个叫做mapToInt的函数可能你应该试试那个方法。你在做什么是完全错误的。 Stream没有这样的东西
  • @manfromnowhere 不工作,因为我有 List 而不是 List 并查看我上面的评论

标签: java-8 functional-programming java-stream


【解决方案1】:

改变

s->s.setId(currServerList
         .stream()
         .filter(server->currServerId.contains(server.getId()))
         .mapToInt(Server::getId)

s->s.setId(currServerList.stream()
         .filter(server->currServerId.contains(server.getId()))
         .mapToInt(Server::getId)
         .findFirst()
         .orElse(0)

答案是假设如果.filter(server-&gt;currServerId.contains(server.getId())) 不匹配任何内容,则让它返回 0 作为默认条件。

您可以将其更改为适合您的默认值。

【讨论】:

  • findFirst().get().getId()) 你对应的代码可以吗?
  • 是的,但如果该值不存在,它可能会引发异常。如果你对它没问题,你也可以这样做
  • 您可以通过更改顺序来消除对每个元素执行两次getId 调用的冗余:.map(Server::getId).filter(currServerId::contains).findFirst().ifPresent(s::setId)。由于源数据是Integer,而目标方法接收Integer,因此在此处使用IntStream 会导致最后不必要的装箱操作。所以你可以只使用map 而不是mapToInt
  • @Holger 我已经更新了我的问题请看最后一个
  • 简单说明上述情况下如何使用函数式编程编写等价代码
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2019-11-08
  • 2022-11-28
  • 2021-02-11
  • 2014-07-03
相关资源
最近更新 更多