返回Optional <user>而不是其中的Optional <bigdecimal>

时间:2019-03-07 18:28:37

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

我正在尝试编写返回最富有的员工的流。

Optional<User> getRichestEmployee() {
    return getUserStream()
        .flatMap(user -> user.getAccounts().stream())
        .map(this::getAccountAmountInPLN)
        .sorted(Comparator.reverseOrder())
        .findFirst();
}

我的方法getAccounts()返回List<Account>

我的方法getAccountAmountInPLN如下:

BigDecimal getAccountAmountInPLN(final Account account) {
    return account
            .getAmount()
            .multiply(BigDecimal.valueOf(account.getCurrency().rate))
            .round(new MathContext(4, RoundingMode.HALF_UP));
}

我的问题是getRichestEmployee()返回Optional<BigDecimal>

我无法return最富有的员工。在流上运行时,我无法访问User对象。如何返回用户?

3 个答案:

答案 0 :(得分:3)

我认为您正在通过查找金额最高的帐户来计算用户的财富。

首先创建一个额外的方法来从用户那里获取金额:

public BigDecimal getUserMaxAmount(User user) {
    return user
            .getAccounts()
            .stream()
            .map(this::getAccountAmountInPLN)
            .max(Comparator.naturalOrder())
            .orElse(BigDecimal.ZERO); //if user has no account I default to 0
}

然后您可以像这样使用它:

Optional<User> getRichestEmployee() {
    return getUserStream()
            .sorted(Comparator.comparing(this::getUserMaxAmount, Comparator.reverseOrder()))
            .findFirst();
}

或更简单:

Optional<User> getRichestEmployee() {
    return getUserStream().max(Comparator.comparing(this::getUserMaxAmount));
}

如果您打算通过汇总所有金额来计算用户的财富,则应通过汇总金额将流减少到单个值:

public BigDecimal getUserTotalAmount(User user) { //instead of getUserMaxAmount
    return user
            .getAccounts()
            .stream()
            .map(this::getAccountAmountInPLN)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

答案 1 :(得分:2)

首先,要找到最富有的员工,您需要对员工账户的金额求和。

第二,要查找总金额最大的员工,请使用max(Comparator<? super T> comparator)

示例:

Optional<User> getRichestEmployee() {
    return getUserStream()
            .max(Comparator.comparing(this::getEmployeeAmountInPLN));
}

BigDecimal getEmployeeAmountInPLN(final User user) {
    return user.getAccounts()
            .stream()
            .map(this::getAccountAmountInPLN)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
}

BigDecimal getAccountAmountInPLN(final Account account) {
    return account
            .getAmount()
            .multiply(BigDecimal.valueOf(account.getCurrency().rate))
            .round(new MathContext(4, RoundingMode.HALF_UP));
}

答案 2 :(得分:-1)

创建自己的比较器,不要将每个帐户都映射到其余额:

Optional<User> getRichestEmployee() {
 return getUserStream()
    .flatMap(user -> user.getAccounts().stream())
    .sorted((a1, a2) -> this.getAccountAmountInPLN(a2).compareTo(this.getAccountAmountInPLN(a1)))
    // Assuming there's a getter for the account owner...
    .map(Account::getOwner) // replace with Account's getter for owner
    .findFirst();