I have a java method written using lambda expressions where i need to add more conditions, and i was forbidden from using classical if and elses. This is my current code that checks if getInstrument has the correct ENUM:
public static Predicate<Deal> isDeal() {
return i ->
i.getInstrument() == ENUM1
|| i.getInstrument() == ENUM2
|| i.getInstrument() == ENUM3;
}
To this code, i need to add a condition that checks if i.getGroup() is null and and then keep checking if the enums are correct. I also need to add a condition that, if i.getGroup() != null and i.getGroup() != "NODEAL" and i.getInstrument() is not an ENUM2 or ENUM3, it returns i. This is how i would write it with classical if and elses:
public static Predicate<Deal> is Deal() {
if ( i.getGroup() == null && i.getInstrument() == ENUM1
|| i.getInstrument() == ENUM2
|| i.getInstrument() == ENUM3) {
return i;
} else if ( i.getGroup() != null && i.getGroup() == "DEAL" &&
i.getInstrument() != ENUM2 || i.getInstrument() != ENUM3) {
return i;
}
}
How could i write this using lambda?
something like
Predicate<Deal> isDeal() {
return deal -> deal.getGroup() == null
&& EnumSet.of(Instrument.ENUM1,
Instrument.ENUM2,
Instrument.ENUM3)
.contains(deal.getInstrument())
||
"DEAL".equals(deal.getGroup())
&& !EnumSet.of(Instrument.ENUM2,
Instrument.ENUM3)
.contains(deal.getInstrument())
}
Something like this
public static Predicate<Deal> isDeal() {
return i->
(i.getGroup() == null
&& (i.getInstrument() == ENUM1
|| i.getInstrument() == ENUM2
|| i.getInstrument() == ENUM3)
)
||
( i.getGroup() != null
&& i.getGroup() == "DEAL"
&& i.getInstrument() != ENUM2 && i.getInstrument() != ENUM3);
}
PS: Keep in mind that you should compare string with equals not ==.
I don't know your business domain, but I tried to make the condition more expressive, readable and maintainable. I would also ask the client why they want it with lambdas because I see no reason to use them here. An if-else statement would give you the same without the overhead.
public Predicate<Deal> isDeal() {
return isGroupAbsent().or(isGroupPresent());
}
private Predicate<Deal> isGroupPresent() {
Instrument i = i.getInstrument();
return d -> "DEAL".equals(d.getGroup()) && i != ENUM2 && i != ENUM3;
}
private Predicate<Deal> isGroupAbsent() {
Instrument i = i.getInstrument();
return d -> d.getGroup() == null && (i == ENUM1 || i == ENUM2 || i == ENUM3);
}
This is a perfect job for the ternary operator ? :
But there still is a problem with your last condition, what should it return, true or false ? Knowing the Predicate<T> signature is boolean test(T t);
public static Predicate<Deal> isDeal() {
return i-> i.getGroup() == null ?
EnumSet.of(ENUM1, ENUM2, ENUM3).contains(i.getInstrument()) :
!"DEAL".equals(i.getGroup()) ?
!EnumSet.of(ENUM2, ENUM3).contains(i.getInstrument()) :
false; // What do you put here? This is missing in your question
}
Related
I have two similar methods in terms of the body, but with a different number of parameters and an extra condition inside. I know there is a way of merging them into a single method using a predicate, but I am not entirely sure how to implement it. Which is the best way to approach this?
public boolean checkIfAllCodesAreUnique(List<String> bsnCodes)
{
List<Businesscode> codes = ConverterUtil.iterableToList(businessCodeService.findAll());
if(codes != null && !codes.isEmpty() && bsnCodes != null && !bsnCodes.isEmpty())
for (String code : bsnCodes)
if (codes.stream().anyMatch(obj -> code.equals(obj.getCode())))
return false;
return true;
}
public boolean checkIfAllCodesAreUnique(List<String> bsnCodes, int idRole)
{
List<Businesscode> codes = ConverterUtil.iterableToList(businessCodeService.findAll());
if(codes != null && !codes.isEmpty() && bsnCodes != null && !bsnCodes.isEmpty())
for (String code : bsnCodes)
if (codes.stream().anyMatch(obj -> code.equals(obj.getCode()) && obj.getId() != idRole))
return false;
return true;
}
public boolean checkIfAllCodesAreUnique(List<String> bsnCodes) {
return isAllCodesAreUnique(bsnCodes, businessCode -> true);
}
public boolean checkIfAllCodesAreUnique(List<String> bsnCodes, int idRole) {
return isAllCodesAreUnique(bsnCodes, businessCode -> businessCode.getId() != idRole);
}
private boolean isAllCodesAreUnique(List<String> bsnCodes, Predicate<Businesscode> checkRole) {
List<Businesscode> businessCodes = Optional.ofNullable(ConverterUtil
.iterableToList(businessCodeService.findAll())).orElse(List.of());
for (String bsnCode : Optional.ofNullable(bsnCodes).orElse(List.of())) {
if (businessCodes.stream()
.filter(businessCode -> bsnCode.equals(businessCode.getCode()))
.anyMatch(checkRole))
return false;
}
return true;
}
Basically predicate would not allow you anything specific in the sense of auto-determinable interface or whatever. Probably the best combination of the two would be:
public boolean checkIfAllCodesAreUnique(List<String> bsnCodes, Integer idRole)
{
List<Businesscode> codes = ConverterUtil.iterableToList(businessCodeService.findAll());
if(codes != null && !codes.isEmpty() && bsnCodes != null && !bsnCodes.isEmpty())
for (String code : bsnCodes)
if (codes.stream().anyMatch(obj -> code.equals(obj.getCode()) || (idRole != null && obj.getId() != idRole))
return false;
return true;
}
And then pass the second parameter as null whenever not available.
private boolean checkStatusAct(Contract contract) {
if (contract.getActs() == null || contract.getActs().isEmpty()) {
return true;
} else if (contract.getActs() != null || (!contract.getActs().isEmpty())) { //here
for (ContractAct contractAct : contract.getActs()) {
if (contractAct.getStatusId() == 15) {
return true;
}
}
}
return false;
}
Isn't it successively checked one by one and if it's not null (!= null || .isEmpty()) it never produces a NullPoi
In Jav 8 or higher version. Assuming contract.getActs() is a list. You don't need to write else: You can do like
private boolean checkStatusAct(Contract contract) {
if (contract.getActs() == null || contract.getActs().isEmpty()) {
return true;
}
return contract.getActs().stream().anyMatch(c -> c.getStatusId() == 15);
}
The problem is that
contract.getActs() != null || (!contract.getActs().isEmpty())
will throw a NullPointerException if contract.getActs() returns null. In that case contract.getActs() != null is false and because of the || operator the JVM must evaluate contract.getActs().isEmpty() which will throw the NullPointerException.
To correct this you should write
contract.getActs() != null && (!contract.getActs().isEmpty())
But this is effectively not needed, because your first if condition already handles the cases where contract.getActs() or contract.getActs().isEmpty(). It would be better to rewrite your code as
private boolean checkStatusAct(Contract contract) {
if (contract.getActs() == null || contract.getActs().isEmpty()) {
return true;
} else {
for (ContractAct contractAct : contract.getActs()) {
if (contractAct.getStatusId() == 15) {
return true;
}
}
}
return false;
}
Starting from Java 8 you can also use streams (navnath's solution).
For some reason, I can't help but see redundancy in this chunk of code. Can anybody help me refactor it be more readable and concise?
if (cachedParty == null || !cachedParty.equals(partyDto)) {
if (cachedParty == null
&& partyDto.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode()))
{
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
} else if (!cachedParty.equals(partyDto)
&& cachedParty.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())
&& !partyDto.getSellerStatusCode()
.equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode())
) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
The comparison to SellerStatusEnum.ACTIVE may be implemented as a function accepting a Supplier<String>
Top level comparison may be simplified to remove cachedParty == null - it is assumed from the code that partyDto is not null and therefore it is enough to check !partyDto.equals(cachedParty)
An example implementation:
Function<Supplier<String>, Boolean> active = x -> SellerStatusEnum.ACTIVE.getCode().equalsIgnoreCase(x.get());
if (!partyDto.equals(cachedParty)) {
boolean partyActive = active.apply(partyDto::getSellerStatusCode);
if (null == cachedParty && partyActive
|| null != cachedParty && !partyActive && active.apply(cachedParty::getSellerStatusCode)
) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
I would suggest making helper method isActive(party) which returns partyDto.getSellerStatusCode().equalsIgnoreCase(SellerStatusEnum.ACTIVE.getCode(). Additionaly, there is a possible NPE when cachedParty == null because !cachedParty.equals(partyDto) is calling equals for null. So, considering that partyDto is never null, this can be reduced to !partyDto.equals(cachedParty).
Also, you're calling same method in if(x) else if (y) statement, so it can be reduced to one if statement with x or y check. So, let's rewrite your statement:
if (A or B) {
if ((A and C) or (B and D and !C)) { F() }
G()
}
As we decided in the first paragraph, A or B = B. So expression now looks like
if (B) {
if ((A and C) or (B and D and !C)) { F() }
G()
}
// and because inside first if statement B = true, we can remove B from nested if:
if (B) {
if ((A and C) or (D and !C)) { F() }
G()
}
So, by doing these optimisations we can get:
if (!partyDto.equals(cachedParty)) {
if (cachedParty == null && isActive(partyDto) || (isActive(cachedParty) && !isActive(partyDto)) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
I've noticed that there is no cachedParty != null check in your nested if, so final result will be look like this:
if (!partyDto.equals(cachedParty)) {
if (cachedParty == null && isActive(partyDto) || (cachedParty != null && isActive(cachedParty) && !isActive(partyDto)) {
pricingControlList.add(convertPartyDtoToPricingControl(partyDto));
}
partyCache.put(partyDto.getSellerServicerNumber(), partyDto);
partiesToSaveOrUpdate.add(partyDto);
}
I saw the code below online. the class override the Object class's hashCode() and equals method. I was just wondering why the return statement of equals() method has to use alternate && and ||? can i just use && all the way through? is there any particular reason why it has to use alternate && and ||?
class Person {
private int id;
private String firstName;
private String lastName;
#Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
Person guest = (Person) obj;
return id == guest.id
&& ((firstName == null ? guest.firstName == null : firstName.equals(guest.firstName))
|| (firstName != null && firstName.equals(guest.getFirstName())))
&& ((lastName == null ? guest.lastName == null : lastName.equals(guest.lastName))
|| (lastName != null && lastName.equals(guest.getLastName())));
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + id;
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
}
Both disjunctions can be replaced with the first operand of ||, since the second operator just covers the second alternative of the tenary operator again (assuming the getter returns the field value)
id == guest.id
&& (firstName == null ? guest.firstName == null : firstName.equals(guest.firstName))
&& (lastName == null ? guest.lastName == null : lastName.equals(guest.lastName));
But I recommend rewriting it as
id == guest.id
&& Objects.equals(firstName, guest.firstName)
&& Objects.equals(lastName, guest.lastName);
The OR condition is used depending of the value of first name or last name respectively taken into account if they are null out not. But that condition is already checked in the second part of the ternary ? : Operator, so you can remove the OR part. The result will be the same
((firstName == null ? guest.firstName == null : firstName.equals(guest.firstName)) || (firstName != null && firstName.equals(guest.getFirstName())))
Suppose I have 4 variables
String a;
String b;
String c;
String d;
I want to check if individual variable or combination of variable is not Null and act accordingly.
For example one way to do this is using if-else this way
if(a!=null && b == null && c == null && d == null) {
//doSomething }
else if(a==null && b!= null && c == null && d == null) {
//doSomething }
else if(a==null && b!= null && c == null && d == null) {
//doSomething }
else if(a==null && b== null && c != null && d == null) {
//doSomething }
......
//Similarly combination of two variables
if(a!=null && b != null && c == null && d == null) {
//doSomething }
else if(a!=null && b== null && c != null && d == null) {
//doSomething }
else if(a!=null && b== null && c == null && d != null) {
//doSomething }
......
//and so on
//Similarly combination of three variables
if(a!=null && b != null && c != null && d == null) {
//doSomething }
else if(a!=null && b== null && c != null && d != null) {
//doSomething }
else if(a!=null && b== null && c == null && d != null) {
//doSomething }
....
How to achieve this kind of situation Switch even don't accept null
I thought of using queue as it dont allow null values but i need to have a key for the variable so that I can get the value and manipulate something. help will be appreciated
You could build an additional variable to achieve this a with switch statement:
int switchvar = 0;
if (a == null) {switchvar += 1;}
if (b == null) {switchvar += 10;}
if (c == null) {switchvar += 100;}
if (d == null) {switchvar += 1000;}
and then you can use
switch (switchvar) {
case(1): //only a ==null
...
case(101): //a == null and c == null
....
case(1011): //a,b,d null
....
case(1111): // all variables null
}