Combining two similar methods in Java with predicate - java

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.

Related

SonarLint "Replace this if-then-else statement by a single return statement"

Im not being able to fix this code smell:
public static boolean esStringVacio(final Object valor) {
if (valor == null) {
return true;
}
String valorTrim = valor.toString().trim();
if ((valorTrim).equals("")) {
return true;
}
if ((valorTrim).equals("null")) {
return true;
}
return false;
}
Tried like so but code smell persist:
if (valor == null || valor.toString().trim().equals("") || valor.toString().trim().equals("null")) {
return true;
} else {
return false;
}
You can shorten it to:
return (valor == null || valor.toString().trim().equals("") || valor.toString().trim().equals("null"));
Edit :
You can shorten even more to:
return ((String.valueOf(valor).trim().equals("null")) || (StringUtils.isBlank(valor)) ;
Thanks to Ernest for suggesting this.
You can combine the last 3 returns into a single OR, and it'd still be reliable / readable.
public static boolean esStringVacio(final Object valor) {
if (valor == null) {
return true;
}
String valorTrim = valor.toString().trim();
return valorTrim.equals("") || valorTrim.equals("null");
}

How to use Java Optional to convert a complex if condition

Consider the following class
Class RequestBodyResource {
private RequestVariable1 att1;
private String att2;
private String att3;
}
I have a method that should return false in 2 conditions
If all the 3 attributes of the RequestBodyResource Object is null/empty
If more than one attribute is not null
Basically "at least one" OR "at most one"
The code for the same is as
public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {
//The below 3 conditions are to test that only one request is present
if(StringUtils.isNotEmpty(request.getAtt3()) && null != request.getAtt1()) {
return false;
}
if(StringUtils.isNotEmpty(request.getAtt2()) && null != request.getAtt1()) {
return false;
}
if(StringUtils.isNotEmpty(request.getAtt3()) && StringUtils.isNotEmpty(request.getAtt2())) {
return false;
}
//The below condition is to test that at least one request is present
if(StringUtils.isEmpty(request.getAtt3()) && null == request.getAtt1() && StringUtils.isEmpty(request.getAtt2())) {
return false;
}
return true;
}
How to use Java 8 Optional to make this code much easier to write and read?
Why not just count?
int count = 0;
if(request.getAtt1() !=null) {
count++;
}
if(StringUtils.isNotEmpty(request.getAtt2())) {
count++;
}
if(StringUtils.isNotEmpty(request.getAtt3())) {
count++;
}
return count == 1;
Version with Optional (do not use, it is added just for fun).
return Optional.ofNullable(request.getAtt1()).map(ignore -> 1).orElse(0)
+ Optional.ofNullable(request.getAtt2()).map(ignore -> 1).orElse(0)
+ Optional.ofNullable(request.getAtt3()).map(ignore -> 1).orElse(0)
== 1;
Also it lack of check of empty strings.
There is no need for an Optional here as such. If you just need to check if at least one of those attributes are present, you could simply check it as:
public boolean validateAtLeastOneRequiredRequestParam(RequestBodyResource request) {
return request.getAtt1() != null
|| !StringUtils.isEmpty(request.getAtt3())
|| !StringUtils.isEmpty(request.getAtt2());
}
Edit 1: For an exactly one check, not so good yet more readable(IMHO) than your current solution would be:
public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {
long countPresentAttribute = Stream.of(request.getAtt2(), request.getAtt3())
.filter(StringUtils::isNotEmpty)
.count() +
Stream.of(request.getAtt1()).filter(Objects::nonNull).count();
return countPresentAttribute == 1;
}
Edit 2: Using Optional and getting rid of an external dependency on StringUtils, you could do it as :
public boolean validateExactlyOneRequiredRequestParam(RequestBodyResource request) {
long countPresentAttribute = Stream.of(
Optional.ofNullable(request.getAtt1()),
Optional.ofNullable(request.getAtt2()).filter(String::isEmpty),
Optional.ofNullable(request.getAtt3()).filter(String::isEmpty))
.filter(Optional::isPresent)
.count();
return countPresentAttribute == 1;
}

Java check if Map values are the same [duplicate]

I need to check if all values in a map are equal. I have a method to perform this task but would like to use a library or native methods. Limitations: Java 5 + Apache Commons libraries.
public static boolean isUnique(Map<Dboid,?> aMap){
boolean isUnique = true;
Object currValue = null;
int iteration = 0;
Iterator<?> it = aMap.entrySet().iterator();
while(it.hasNext() && isUnique){
iteration++;
Object value = it.next();
if(iteration > 1){
if (value != null && currValue == null ||
value == null && currValue != null ||
value != null && currValue != null & !value.equals(currValue)) {
isUnique = false;
}
}
currValue = value;
}
return isUnique;
}
What about this something like this:
Set<String> values = new HashSet<String>(aMap.values());
boolean isUnique = values.size() == 1;
how about
return (new HashSet(aMap.values()).size() == 1)
I know the original questions asks for solutions in Java 5, but in case someone else searching for an answer to this question is not limited to Java 5 here is a Java 8 approach.
return aMap.values().stream().distinct().limit(2).count() < 2
You could store the values in a Bidirectional Map and always have this property.
public static boolean isUnique(Map<Dboid,?> aMap) {
Set<Object> values = new HashSet<Object>();
for (Map.Entry<Dboid,?> entry : aMap.entrySet()) {
if (!values.isEmpty() && values.add(entry.getValue())) {
return false;
}
}
return true;
}
This solution has the advantage to offer a memory-saving short cut if there are many differences in the map. For the special case of an empty Map you might choose false as return value, change it appropriately for your purpose.
Or even better without a Set (if your Map does not contain null-values):
public static boolean isUnique(Map<Dboid,?> aMap) {
Object value = null;
for (Object entry : aMap.values()) {
if (value == null) {
value = entry;
} else if (!value.equals(entry)) {
return false;
}
}
return true;
}
As my comment above:
//think in a more proper name isAllValuesAreUnique for example
public static boolean isUnique(Map<Dboid,?> aMap){
if(aMap == null)
return true; // or throw IlegalArgumentException()
Collection<?> c = aMap.getValues();
return new HashSet<>(c).size() <= 1;
}

How to handle null values when doing Collections.sort() with nested objects?

What is the best way to deal with null values, when doing Collections.sort() on nested objects?
I'd like to sort a couple of objects, basically applying this rule:
#Override
public int compare(final InvoicePos invoicePosOne, final InvoicePos invoicePosTwo) {
return invoicePosOne.getInvoice().getInvoiceNo().compareTo(invoicePosTwo.getInvoice().getInvoiceNo());
}
However, any of these objects can be null (i.e. invoice position, invoice and invoice number).
public class InvoicePos {
private Invoice invoice = null;
// ...
}
public class Invoice {
private String invoiceNo = "";
// ...
}
Do I have do do explicit null-checks on all my objects or is there an approach with less writing?
For clarification: I'm aware that my above example may raise NullPointerExceptions. Currently I'm doing the following and basically, I questioned myself, if there is any smarter approach.
Collections.sort(allInvoicePositions, new Comparator<InvoicePos>() {
#Override
public int compare(final InvoicePos invoicePosOne, final InvoicePos invoicePosTwo) {
if (null == invoicePosOne && null == invoicePosTwo) {
return 0;
}
if (null == invoicePosOne) {
return -1;
}
if (null == invoicePosTwo) {
return 1;
}
if (null == invoicePosOne.getInvoice() && null == invoicePosTwo.getInvoice()) {
return 0;
}
if (null == invoicePosOne.getInvoice()) {
return -1;
}
if (null == invoicePosTwo.getInvoice()) {
return 1;
}
if (null == invoicePosOne.getInvoice().getInvoiceNo() && null == invoicePosTwo.getInvoice().getInvoiceNo()) {
return 0;
}
if (null == invoicePosOne.getInvoice().getInvoiceNo()) {
return -1;
}
if (null == invoicePosTwo.getInvoice().getInvoiceNo()) {
return 1;
}
return invoicePosOne.getInvoice().getInvoiceNo().compareTo(invoicePosTwo.getInvoice().getInvoiceNo());
}
});
There is something called as NullComparator in org.apache.commons.collections.jar.
This might help you https://commons.apache.org/proper/commons-collections/javadocs/api-2.1.1/org/apache/commons/collections/comparators/NullComparator.html.
Do I have do do explicit null-checks on all my objects or is there an approach with less writing?
If these values don't represent anything in your collection, then the best thing you can do is avoid them; don't allow inserting them, so you won't have to handle them when comparing items.
If you insist to have them, then you must check if they're null to avoid NullPointerException.
If you have null values then you need to handle them explicitly and in a consistent way so to have a valid ordering relation. That is, something like:
compare (a, b) {
if (a == null && b == null) return 0;
if (a == null) return -1;
if (b == null) return +1;
return comp(a,b);
}
Don't be tempted to do something like:
compare (a, b) {
if (a == null || b == null) return -1;
return comp(a,b);
}
which would break the ordering relation.

Remove Repeated Code

My Question is-
I have two string variables site_inclusion and site_exclusion. If site_inclusion has a value, then I don't care what values site_exclusion contains. That is to say that site_inclusion overrides site_exclusion. If, however, site_inclusion is null and site_exclusion has a value, then I want to examine site_exclusion.
To be more precise:
If site_inclusion and site_exclusion are both null then set useTheSynthesizer as true;
If site_inclusion is not null and it matches with the regexPattern then set useTheSynthesizer as true. And I don't care what values are there in site_exclusion.
If site_inclusion is null and site_exclusion is not null and site_exclusion does not match the regexPattern then set useTheSynthesizer to true.
I wrote the below code but somehow I think, I am repeating some stuff here in the if/else loop. Any code improvements will be appreciated that fulfill my conditions.
String site_inclusion = metadata.getSiteInclusion();
String site_exclusion = metadata.getSiteExclusion();
// fix for redundant data per site issue
if(site_inclusion != null && site_inclusion.matches(regexPattern)) {
useTheSynthesizer = true;
} else if(site_exclusion != null && !(site_exclusion.matches(regexPattern))) {
useTheSynthesizer = true;
} else if(site_inclusion == null && site_exclusion == null ) {
useTheSynthesizer = true;
}
You don't really need the last null test.
I (personally) find it poor style to do an if(test == true) flag = true statement. You can simply say flag = test.
My recommendation would be:
if(site_inclusion != null)
{
useTheSynthesizer = site_inclusion.matches(regexPattern);
}
else if(site_exclusion != null)
{
useTheSynthesizer = ! site_exclusion.matches(regexPattern);
}
else
{
useTheSynthesizer = true;
}
You could also do it in a oneliner:
useTheSynthesizer = site_inclusion != null ? site_inclusion.matches(regexPattern) : (site_exclusion != null ? ! site_exclusion.matches(regexPattern) : true);
But I find that sort of obnoxious to read.
(Note, I made the assumption that useTheSynthesizer was otherwise false. This isn't explicit in your code or explanation, but I think this assumption was safe.)
I would do it like this:
boolean useTheSynthesizer;
if (siteInclusion == null && siteExclusion == null) {
useTheSynthesizer = true;
}
else if (siteInclusion == null) {
useTheSynthesizer = ( ! siteExclusion.matches(regexPattern) );
}
else {
useTheSynthesizer = siteInclusion.matches(regexPattern);
}
I also removed the underscores from your variable names, since they do not fit the java naming conventions (and they're hideous IMO).
You can do like this. Basically i extracted all the conditions as small methods and made as OR condition.
String site_inclusion = metadata.getSiteInclusion();
String site_exclusion = metadata.getSiteExclusion();
if(isInclusionAndExclusionNull(site_inclusion, site_exclusion) || isSiteExclusionMatches(site_exclusion, regexPattern) || isSiteInclusionMatches(site_inclusion, regexPattern)) {
useTheSynthesizer = true;
}
private static boolean isInclusionAndExclusionNull(String site_inclusion,
String site_exclusion) {
return site_inclusion == null && site_exclusion == null;
}
private boolean isSiteExclusionMatches(String site_exclusion,
String regexPattern) {
return site_exclusion != null && !(site_exclusion.matches(regexPattern));
}
private boolean isSiteInclusionMatches(String site_inclusion,
String regexPattern) {
return site_inclusion != null && site_inclusion.matches(regexPattern);
}
You can have 2 methods for flexibility to process the inclusions and exclusions like below..
callingMethod() {
boolean useTheSynthesizer = processSiteInclusions(site_inclusion, regexPattern);
if (useTheSynthesizer == false) {
useTheSynthesizer = processSiteExclusions(site_inclusion, regexPattern);
}
if (useTheSynthesizer == false) {
useTheSynthesizer = true;
}
}
private boolean processSiteInclusions(site_inclusion, regexPattern) {
boolean useSynthesizer = false;
if (site_inclusion != null && !site_inclusion.matches(regexPattern))
useSynthesizer = true;
return useSynthesizer;
}
private boolean processSiteExclusions(site_exclusion, regexPattern) {
boolean useSynthesizer = false;
if (site_exclusion != null && !site_inclusion.matches(regexPattern))
useSynthesizer = true;
return useSynthesizer;
}
Hello I think you can improve it using some like OR, and no only AND or try somethin like swicht case.
Anyways you can create some function that tested your variables, and you can write this confusing code out from your main module.
For example you can write this code in a function called boolean TestingVariable ( String X, String Y);
For example:
boolean TesteingVariable ( String X, String Y){
if(X != null && X.matches(regexPattern)) {
return true;
} else if(Y != null && !(Y.matches(regexPattern))) {
return = true;
} else if(X == null && Y == null ) {
return = true;
}
};
On this way your final main module code will be something like this and you will avoid the confused code in your main code:
String site_inclusion = metadata.getSiteInclusion();
String site_exclusion = metadata.getSiteExclusion();
// fix for redundant data per site issue
useTheSynthesizer = TesteingVariable (site_inclusion ,site_exclusion);
I think you should enter the variable regexPattern in the function.
Sorry for my English I hope you can undertand all and it help to you.

Categories