0

I am new to java so I need help with the below scenario.

I have an ArrayList that stores dates and other information, I want to print the arraylist in which the last 3 days' dates should be on top, the rest is following the same list.

Any help would be appreciated.

package learn.java.com;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class Person {

private String orderno;
private String itemno;
private Date orderdate;

public String getOrderno() {
    return orderno;
}

public void setOrderno(String orderno) {
    this.orderno = orderno;
}

public String getItemno() {
    return itemno;
}

public void setItemno(String itemno) {
    this.itemno = itemno;
}

public Date getOrderdate() {
    return orderdate;
}

public void setOrderdate(Date orderdate) {
    this.orderdate = orderdate;
}

public Person(String orderno, String itemno, Date orderdate) {
    this.orderno = orderno;
    this.itemno = itemno;
    this.orderdate = orderdate;
}





public static void main(String[] args) throws ParseException {
    ArrayList<Person> list = new ArrayList<>();
    list.add(new Person("099909","BC101", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2010")));
    list.add(new Person("989878","BC102", new SimpleDateFormat("dd-MM-yyyy").parse("02-01-1990")));
    list.add(new Person("878788","BC103", new SimpleDateFormat("dd-MM-yyyy").parse("03-01-2000")));
    list.add(new Person("099909","BC104", new SimpleDateFormat("dd-MM-yyyy").parse("04-01-2010")));
    list.add(new Person("989878","BC105", new SimpleDateFormat("dd-MM-yyyy").parse("05-01-1990")));
    list.add(new Person("878788","BC106", new SimpleDateFormat("dd-MM-yyyy").parse("06-01-2000")));
    list.add(new Person("099909","BC107", new SimpleDateFormat("dd-MM-yyyy").parse("07-01-2010")));
    list.add(new Person("989878","BC108", new SimpleDateFormat("dd-MM-yyyy").parse("08-01-1990")));
    list.add(new Person("878788","BC109", new SimpleDateFormat("dd-MM-yyyy").parse("09-01-2000")));

    System.out.println("Before Sort");
    for (Person person : list) {
        System.out.println(person.orderno + " " + person.getItemno()+ " " + person.getOrderdate());
    }



   }
  }

"CURRENT OUTPUT"

099909 BC101 Fri Jan 01 00:00:00 EST 2010

989878 BC102 Tue Jan 02 00:00:00 EST 1990

878788 BC103 Mon Jan 03 00:00:00 EST 2000

099909 BC104 Mon Jan 04 00:00:00 EST 2010

989878 BC105 Fri Jan 05 00:00:00 EST 1990

878788 BC106 Thu Jan 06 00:00:00 EST 2000

099909 BC107 Thu Jan 07 00:00:00 EST 2010

989878 BC108 Mon Jan 08 00:00:00 EST 1990

878788 BC109 Sun Jan 09 00:00:00 EST 2000

I WANT TO SEE OUTPUT LIKE THIS

099909 BC107 Thu Jan 07 00:00:00 EST 2010

989878 BC108 Mon Jan 08 00:00:00 EST 1990

878788 BC109 Sun Jan 09 00:00:00 EST 2000

099909 BC101 Fri Jan 01 00:00:00 EST 2010

989878 BC102 Tue Jan 02 00:00:00 EST 1990

878788 BC103 Mon Jan 03 00:00:00 EST 2000

099909 BC104 Mon Jan 04 00:00:00 EST 2010

989878 BC105 Fri Jan 05 00:00:00 EST 1990

878788 BC106 Thu Jan 06 00:00:00 EST 2000

Thanks

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • we need more infos to help you, like how your `ArrayList` stores dates and "other information". See [How to ask](https://stackoverflow.com/help/how-to-ask) – Crih.exe Aug 10 '21 at 17:46
  • https://stackoverflow.com/questions/5245093/how-do-i-use-comparator-to-define-a-custom-sort-order – Ivan Aug 10 '21 at 17:50
  • 2
    Oh *please* don't use `SimpleDateFormat`, it's obsolete and replaced by `java.time.format.DateTimeFormatter`. – MC Emperor Aug 10 '21 at 23:34
  • I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Aug 11 '21 at 04:51
  • Similar (only next 3 days instead): [Sorting collection date field between two given dates](https://stackoverflow.com/questions/68700048/sorting-collection-date-field-between-two-given-dates) – Ole V.V. Aug 11 '21 at 04:53
  • We need more clarity, please. Do you want to ignore year when deciding which are the last three days? If December 31 had been in your list, would it have counted as earlier or later than the others when deciding which are the last three days? – Ole V.V. Aug 11 '21 at 05:17
  • Also when the last date is January 9, do you want to see all persons with order date January 7, 8 and 9 first no matter if they are 1 person or 10 persons? – Ole V.V. Aug 11 '21 at 05:47
  • For your coming Stack Overflow questions you should also learn to show an effort on your own part for better reception. Questions showing no effort are very often downvoted and closed quickly. Even doing a simple search and noting in the question that you know that you need to use the sort method of your list and the `Comparator` interface but you don’t know how is better than nothing and will make more people prepared to make an effort to help you. – Ole V.V. Aug 11 '21 at 05:55

2 Answers2

2

Here is a simplified example, using Java streams, and replacing your murky Person-Order-LineItem combo class with a simple Employee class.

I define our Employee class as a Java 16+ record for brevity, but not important.

record Employee( int id , String name , LocalDate hired ) { }

Notice that we use java.time.LocalDate, as you seem to want a date without a time-of-day. Tip: Never use java.util.Date, nor Calendar or SimpleDateFormat. These legacy classes are terribly flawed in design, and were supplanted years ago by the modern java.time classes defined in JSR 310.

Create some sample data.

List < Employee > employeeList =
        List.of(
                new Employee( 1 , "Alice" , LocalDate.of( 2021 , Month.AUGUST , 10 ) ) ,
                new Employee( 1 , "Bob" , LocalDate.of( 2021 , Month.AUGUST , 9 ) ) ,
                new Employee( 2 , "Carol" , LocalDate.of( 2021 , Month.AUGUST , 8 ) ) ,
                new Employee( 3 , "Davis" , LocalDate.of( 2021 , Month.JANUARY , 23 ) ) ,
                new Employee( 4 , "Ernestine" , LocalDate.of( 2021 , Month.JANUARY , 24 ) ) ,
                new Employee( 5 , "Frank" , LocalDate.of( 2021 , Month.JANUARY , 25 ) )
        );

Determine today's date. Time zone is important; for any given moment the date varies around the globe by time zone.

For this demo, we replace that dynamically-determined date with a hard-coded date.

// LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
LocalDate today = LocalDate.of( 2021 , Month.AUGUST , 10 );
LocalDate threeDaysAgo = today.minusDays( 3 );

Filter for the Employee objects whose hire-date is within the last three days. Collect into a NavigableSet where their order is maintained according to the Comparator we pass to constructor.

For convenience, we use Comparator.comparing. We pass a method reference Employee :: hired, the default getter method implicitly created by the compiler for a record.

NavigableSet < Employee > recent = new TreeSet <>( Comparator.comparing( Employee :: hired ) );
recent.addAll( employeeList.stream().filter( employee -> ! employee.hired.isBefore( threeDaysAgo ) ).collect( Collectors.toUnmodifiableSet() ) );

Determine our longer-term employees by filtering the list for those objects not found in our recent set.

NavigableSet < Employee > older = new TreeSet <>( Comparator.comparing( Employee :: hired ) );
older.addAll( employeeList.stream().filter( employee -> ! recent.contains( employee ) ).collect( Collectors.toUnmodifiableSet() ) );

You want a single list. So add the recent set to a new list, to be followed by adding the older set.

The iteration order in which the elements are added to our list is controlled by the fact that we used NavigableSet implementations that maintained a certain order.

List < Employee > results = new ArrayList <>( employeeList.size() );
results.addAll( recent );
results.addAll( older );

Dump to console.

System.out.println( "employeeList = " + employeeList );
System.out.println( "recent = " + recent );
System.out.println( "older = " + older );
System.out.println( "results = " + results );

When run.

employeeList = [Employee[id=1, name=Alice, hired=2021-08-10], Employee[id=1, name=Bob, hired=2021-08-09], Employee[id=2, name=Carol, hired=2021-08-08], Employee[id=3, name=Davis, hired=2021-01-23], Employee[id=4, name=Ernestine, hired=2021-01-24], Employee[id=5, name=Frank, hired=2021-01-25]]

recent = [Employee[id=2, name=Carol, hired=2021-08-08], Employee[id=1, name=Bob, hired=2021-08-09], Employee[id=1, name=Alice, hired=2021-08-10]]

older = [Employee[id=3, name=Davis, hired=2021-01-23], Employee[id=4, name=Ernestine, hired=2021-01-24], Employee[id=5, name=Frank, hired=2021-01-25]]

results = [Employee[id=2, name=Carol, hired=2021-08-08], Employee[id=1, name=Bob, hired=2021-08-09], Employee[id=1, name=Alice, hired=2021-08-10], Employee[id=3, name=Davis, hired=2021-01-23], Employee[id=4, name=Ernestine, hired=2021-01-24], Employee[id=5, name=Frank, hired=2021-01-25]]

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
0

Thanks for helping me that's working now.

double pastFiveDays = DoubleTime.getDoubleDate(LocalDate.now().minusDays(5));

    ArrayList<Header> salesList = list.getSalesHeaders();
        NavigableSet < Header> recent = new TreeSet<>( Comparator.comparing( Header:: getSalesDate ) );
        recent.addAll( salesList.stream().filter( salesorder -> (salesorder.getSalesDate() > pastFiveDays && salesorder.getUnit() !=1))
                .collect( Collectors.toCollection(ArrayList::new) ) );

        NavigableSet < Header> older = new TreeSet <>( Comparator.comparing( Header:: getSalesDate ) );
        older.addAll( salesList.stream().filter( salesorder -> ! recent.contains( salesorder ) && salesorder.getUnit() !=1 )
                .collect( Collectors.toCollection(ArrayList::new) ) );