首页 > 解决方案 > 使用函数式编程对列表中的服务器对象进行流和过滤

问题描述

我有两个List<Server>current 和List<Server>serverList,但我想从 serverList 中已经存在的 current 中过滤掉 Server。

现在它将检查的唯一List<IPAddress>性是上面两个列表中的哪个。

IPAddress POJO 有两个字段 Stringipaddress, boolean primary

列表有多个辅助 ip,但有一个唯一的主 ip,因此我们需要根据这个主 ip 过滤掉,我们只能检查它是否为布尔真,才能知道它的主 ip。

我认为这会产生一个非常复杂的流过滤器逻辑,因此我需要我尝试过的帮助,但我不是函数式编程方面的专家。

serverList.stream().filter(new Predicate<? extends Server>() {

                })

错误:Stream 类型中的方法 filter(Predicate) 不适用于参数 (new Predicate(){})

服务器 POJO 具有与 IPAddress 相同的 getter 和 setter。列表在此服务器 POJO 中作为 getter 和 setter。

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;
    }


}

标签: java-8functional-programming

解决方案


这其实很简单。

首先,在Server中添加一个方法来获取它的主地址:

public String getPrimaryIpAddress() {
    return ipaddresses.stream()
        .filter(IPAddress::isPrimary)
        .findAny()
        .orElseThrow(() -> new IllegalStateException("there should be a primary address")
        .getIpaddress();
}

然后创建一组主地址

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

然后过滤服务器列表:

List<Server> currrent = ...

List<Server> filtered = current.stream()
    .filter(s -> !primaryIpAddresses.contains(s.getPrimaryIpAddress()))
    .collect(Collectors.toList());

推荐阅读