Summary Table

Categories Total Count
PII 0
URL 0
DNS 0
EKL 0
IP 0
PORT 0
VsID 0
CF 0
AI 0
VPD 0
PL 0
Other 0

File Content

package gov.va.med.ewv.util;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Comparator;
//import java.util.Optional;
//import java.util.OptionalInt;
import java.util.function.Function;

public class NullsLastComparator {
// Provide useful comparators for building new comparators
// Here, we use nullsLast.
// because I think that people want to see the "real" data before any "missing" data.
public static final Comparator<String> nullsLastStringComparator = Comparator.nullsLast(String::compareTo);
public static final Comparator<BigDecimal> nullsLastBigDecimalComparator = Comparator.nullsLast(BigDecimal::compareTo);
public static final Comparator<LocalDate> nullsLastLocalDateComparator = Comparator.nullsLast(LocalDate::compareTo);

// Some strings sort differently, because of their semantics

// Using OptionalInt
// private static final OptionalInt oInt(String s) {
// try {
// return OptionalInt.of(Integer.parseInt(s));
// } catch (NumberFormatException ex) {}
// return OptionalInt.empty();
//}
//
//public static final Comparator<String> nullsLastIntegerStringComparator = (a,b) -> {
// OptionalInt ia = oInt(a);
// OptionalInt ib = oInt(b);
// return Integer.compare(ia.orElse(Integer.MAX_VALUE), ib.orElse(Integer.MAX_VALUE));
//};
//// Do not overload Comparator<String>

private static final int parseIntOrElseMAX_VALUE(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException ex) {}
return Integer.MAX_VALUE;
}

public static final Comparator<String> nullsLastIntegerStringComparator = (a,b) -> {
return Integer.compare(parseIntOrElseMAX_VALUE(a), parseIntOrElseMAX_VALUE(b));
};
// Do not overload Comparator<String>

private static final DateTimeFormatter dTF_USA = DateTimeFormatter.ofPattern("MM/dd/yyyy"); // is there an official format?
public static final LocalDate localDateUSA(String datestring) {
LocalDate localDate = null;
if (datestring == null) {
return localDate; // Avoid NPE from LocalDate.parse
}
try {
localDate = LocalDate.parse(datestring, dTF_USA);
} catch (DateTimeParseException ex) { }
return localDate;
};

// public static final Function<String, LocalDate> localDateUSA = (String datestring) -> {
// LocalDate localDate = null;
// if (datestring == null) {
// return localDate; // Avoid NPE from LocalDate.parse
// }
// try {
// localDate = LocalDate.parse(datestring, dTF_USA);
// } catch (DateTimeParseException ex) { }
// return localDate;
// };
//
public static final Comparator<String> nullsLastLocalDateStringComparator =
Comparator
.comparing(NullsLastComparator::localDateUSA, nullsLastLocalDateComparator)
;
// Cannot overload because <String> is already used.
// ?? Could we public class LocalDateString extends String {...}
// and then
// public static final Comparator<LocalDateString> nullsLastLocalDateStringComparator =
// Comparator
// .comparing(localDateUSA, nullsLastLocalDateComparator)
// ;
//
// public static int compare(LocalDateString a, LocalDateString b){
// // Requirement is to sort first on getBeginDateOfService and getProcedureCode
// return nullsLastLocalDateStringComparator.compare(a,b);
// }

public static int compare(BigDecimal a, BigDecimal b){
// Requirement is to sort first on getBeginDateOfService and getProcedureCode
return nullsLastBigDecimalComparator.compare(a,b);
}

public static int compare(LocalDate a, LocalDate b){
// Requirement is to sort first on getBeginDateOfService and getProcedureCode
return nullsLastLocalDateComparator.compare(a,b);
}

// Add overloaded functions only for "distinctive" types.
// Namely String is too generic, as safeLocalDateVs and safeStringVs are both for String arguments!
public static int compare(String a, String b){
// Requirement is to sort first on getBeginDateOfService and getProcedureCode
return nullsLastStringComparator.compare(a,b);
}
// public static int vs(String a, String b){
// // Requirement is to sort first on getBeginDateOfService and getProcedureCode
// return safeLocalDateStringVs.compare(a,b);
// }

}