Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort List of objects by date and applying filter

I have list of Payments:

Payment 1
  CountyTaxAmount = 250.00
  CityTaxAmount   = 101.00
  LienAmount      = 0.00
  HazardAmount    = 0.00
  PaymentDueDate  = "2018-06-01"

Payment 2
  CountyTaxAmount = 10.00
  CityTaxAmount = 20.00
  LienAmount      = 0.00
  HazardAmount    = 0.00
  PaymentDueDate = "2018-05-01"

I created a function that takes in this list and currentDueDate. If paymentDueDate is equal to or before currentDueDate and one that's closest to currentDueDate, I want to use that row in my calculations.

For some reason my sort is not working properly. Can someone shed some light on what I am doing wrong. Here is my code:

private EscrowStatusEnum determineEscrowStatus(Payment pcm, LocalDate currentDueDate) {
    EscrowStatusEnum escrowStatus = null;

    if(currentDueDate!= null && pcm!=null 
            && pcm.getPayment() != null 
            && !pcm.getPayment().isEmpty()) {

        Predicate<Payment> pcmRow = 
                it->it.getPaymentDueDate()!=null && !it.getPaymentDueDate().isAfter(currentDueDate);

        final Payment sortedRow = 
                pcm.getPayment().stream().sorted((el1, el2) -> el1.getPaymentDueDate().compareTo(el2.getPaymentDueDate())).
                filter(pcmRow).findFirst().orElse(null);

        if(sortedRow != null) {

            BigDecimal countyCityLienHazardSum = sortedRow.getCountyTaxAmount().add(sortedRow.getCityTaxAmount()).add(sortedRow.getLienAmount()).add(sortedRow.getHazardAmount());
            BigDecimal countyCityLienSum = sortedRow.getCountyTaxAmount().add(sortedRow.getCityTaxAmount()).add(sortedRow.getLienAmount());

            if(countyCityLienHazardSum.compareTo(BigDecimal.ZERO) == 0)
                escrowStatus = EscrowStatusEnum.NONESCROWED;
            else if(countyCityLienSum.compareTo(BigDecimal.ZERO) > 0 && sortedRow.getHazardAmount().compareTo(BigDecimal.ZERO) == 0 ||
                    countyCityLienSum.compareTo(BigDecimal.ZERO) >= 0 && sortedRow.getHazardAmount().compareTo(BigDecimal.ZERO) > 0)
                escrowStatus = EscrowStatusEnum.ESCROWED;
        }
    }

    return escrowStatus;
}

When I pass in currentDueDate of "2018-06-01", I want my code to return Payment 1.

Currently it is returning Payment 2.

If I remove Payment 2 from my tests, then it returns Payment 1.

So something must be wrong with sort.

like image 706
Angelina Avatar asked Jan 11 '19 22:01

Angelina


People also ask

How do you sort an array of objects by date?

To sort an array of objects by date property: Call the sort() method on the array. Subtract the date in the second object from the date in the first. Return the result.

How do you sort a list of objects based on value?

In the main() method, we've created an array list of custom objects list, initialized with 5 objects. For sorting the list with the given property, we use the list's sort() method. The sort() method takes the list to be sorted (final sorted list is also the same) and a comparator.

How do I sort a list by date?

Inside the compare method for return value use the compareTo() method which will return the specified value by comparing the DateItem objects. Now in the main method use Collections. sort() method and pass the ArrayList and 'SortItem' class object to it, it will sort the dates, and output will be generated.


1 Answers

Your sort returns the earliest date. What you want is the latest date that is earlier than the cutoff.

To find the smallest or largest value in a stream, don't use sort(...).findFirst(). Use max or min instead. In your case:

sortedRow = pcm.getPayment().stream()
               .filter(pcmRow)
               .max(Comparator.comparing(Payment::getPaymentDueDate))
               .orElse(null);   // not relevant to your question but consider not using nulls so much
like image 72
Misha Avatar answered Sep 24 '22 02:09

Misha