What I do is simply user can do trade but first I need to check balance of accounts(usdt & bitcoin account). Simple thing is that for buying I only check usdt account balance and for selling I only check crypto balance but the problem is that these accounts can be null too, thats why I need to use Optional.
Here is my comparing code;
private boolean isBalanceAvailableForTrade(TradeRequestDto requestDto, List<Account> accountList) {
Optional<Account> dollarAccount = accountList.stream()
.filter(account -> account.getAccountCurrencyType().equals(Currency.USDT.toString()))
.findFirst();
Optional<Account> cryptoAccount = accountList.stream()
.filter(account -> account.getAccountCurrencyType().equals(requestDto.getCurreny()))
.findFirst();
if (requestDto.getOperationType().equalsIgnoreCase(BUY)) {
if (dollarAccount.get().getAmount().compareTo(BigDecimal.valueOf(0)) > 0) {
return true;
}
//TODO throw no available amount exception etc.
return false;
}
if (requestDto.getOperationType().equalsIgnoreCase(SELL)) {
if(cryptoAccount.get().getAmount().compareTo(BigDecimal.valueOf(0)) > 0) {
return true;
}
//TODO throw no available amount exception etc.
return false;
}
return false;
}
My problem is actually I am not checking if the accounts are null above, the line
`if (dollarAccount.get().getAmount().compareTo(BigDecimal.valueOf(0)) > 0)` may throw *NullPointerException*.
I need something like :
dollarAccount.ifPresent(()-> {then do multiple line of code/operation} ).orElseThrow(some exception)
I am pretty near to solution I think but I cannot figure out how to implement Optional for multiple check(balance check and null check). How should I refactor this piece of code properly ?
Side note: I am not sure if the following account check is also best practice or not and if you can give suggestion, it is more than welcome
Optional<Account> dollarAccount = accountList.stream()
.filter(account -> account.getAccountCurrencyType().equals(Currency.USDT.toString()))
.findFirst();
CodePudding user response:
.orElseThrow() returns the contained value, so you just use it instead of .get():
dollarAccount.orElseThrow(() -> new Exception()).getAmount().compareTo(BigDecimal.valueOf(0)) > 0
Maybe just split it up, so that it doesn't get too long (and possibly drop the if):
Account account = dollarAccount.orElseThrow(() -> new Exception());
return account.getAmount().compareTo(BigDecimal.valueOf(0)) > 0;
CodePudding user response:
You should avoid using get on an Optional. You can unpack an optional using orElseThrow as follows:
Account account = dollarAccount.orElseThrow(() -> new NotFoundException("Dollar account not found!));
This will either return an Account or throw an exception if the optinal is emtpy.
For your side note:
Your stream looks correct, it will return an empty optinal if accountList is empty or if the filter would not find any account. Otherwise, the filtering will stop at the first account found.
