How to find Max Date in List<Object>?

前端 未结 6 2190
被撕碎了的回忆
被撕碎了的回忆 2020-12-23 19:13

Consider a class User

public class User{
  int userId;
  String name;
  Date date;
}

Now I have a List

相关标签:
6条回答
  • 2020-12-23 19:27

    You should not call .get() directly. Optional<>, that Stream::max returns, was designed to benefit from .orElse... inline handling.

    If you are sure your arguments have their size of 20:

    list.stream()
        .map(u -> u.date)
        .max(Date::compareTo)
        .orElseThrow(() -> new IllegalArgumentException("Expected a list of size: 20. Was: 0"));
    

    If you support empty lists, then return some default value, for example:

    list.stream()
        .map(u -> u.date)
        .max(Date::compareTo)
        .orElse(new Date(Long.MIN_VALUE));
    

    CREDITS to: @JimmyGeers, @assylias from the accepted answer.

    0 讨论(0)
  • 2020-12-23 19:34

    A small improvement from the accepted answer is to do the null check and also get full object.

    public class DateComparator {
    
    public static void main(String[] args) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1, "name1", addDays(new Date(), 1)));
        employees.add(new Employee(2, "name2", addDays(new Date(), 3)));
        employees.add(new Employee(3, "name3", addDays(new Date(), 6)));
        employees.add(new Employee(4, "name4", null));
        employees.add(new Employee(5, "name5", addDays(new Date(), 4)));
        employees.add(new Employee(6, "name6", addDays(new Date(), 5)));
        System.out.println(employees);
        Date maxDate = employees.stream().filter(emp -> emp.getJoiningDate() != null).map(Employee::getJoiningDate).max(Date::compareTo).get();
        System.out.println(format.format(maxDate));
        //Comparator<Employee> comparator = (p1, p2) -> p1.getJoiningDate().compareTo(p2.getJoiningDate());
        Comparator<Employee> comparator = Comparator.comparing(Employee::getJoiningDate);
        Employee maxDatedEmploye = employees.stream().filter(emp -> emp.getJoiningDate() != null).max(comparator).get();
        System.out.println(" maxDatedEmploye : " + maxDatedEmploye);
    
        Employee minDatedEmployee = employees.stream().filter(emp -> emp.getJoiningDate() != null).min(comparator).get();
        System.out.println(" minDatedEmployee : " + minDatedEmployee);
    
    }
    
    public static Date addDays(Date date, int days) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DATE, days); // minus number would decrement the days
        return cal.getTime();
    }
    }
    

    You would get below results :

     [Employee [empId=1, empName=name1, joiningDate=Wed Mar 21 13:33:09 EDT 2018],
    Employee [empId=2, empName=name2, joiningDate=Fri Mar 23 13:33:09 EDT 2018],
    Employee [empId=3, empName=name3, joiningDate=Mon Mar 26 13:33:09 EDT 2018],
    Employee [empId=4, empName=name4, joiningDate=null],
    Employee [empId=5, empName=name5, joiningDate=Sat Mar 24 13:33:09 EDT 2018],
    Employee [empId=6, empName=name6, joiningDate=Sun Mar 25 13:33:09 EDT 2018]
    ]
    2018-03-26
     maxDatedEmploye : Employee [empId=3, empName=name3, joiningDate=Mon Mar 26 13:33:09 EDT 2018]
    
     minDatedEmployee : Employee [empId=1, empName=name1, joiningDate=Wed Mar 21 13:33:09 EDT 2018]
    

    Update : What if list itself is empty ?

            Date maxDate = employees.stream().filter(emp -> emp.getJoiningDate() != null).map(Employee::getJoiningDate).max(Date::compareTo).orElse(new Date());
        System.out.println(format.format(maxDate));
        Comparator<Employee> comparator = Comparator.comparing(Employee::getJoiningDate);
        Employee maxDatedEmploye = employees.stream().filter(emp -> emp.getJoiningDate() != null).max(comparator).orElse(null);
        System.out.println(" maxDatedEmploye : " + maxDatedEmploye);
    
    0 讨论(0)
  • 2020-12-23 19:35
    Comparator<User> cmp = new Comparator<User>() {
        @Override
        public int compare(User user1, User user2) {
            return user1.date.compareTo(user2.date);
        }
    };
    
    Collections.max(list, cmp);
    
    0 讨论(0)
  • 2020-12-23 19:37

    Just use Kotlin!

    val list = listOf(user1, user2, user3)
    val maxDate = list.maxBy { it.date }?.date
    
    0 讨论(0)
  • 2020-12-23 19:46

    Since you are asking for lambdas, you can use the following syntax with Java 8:

    Date maxDate = list.stream().map(u -> u.date).max(Date::compareTo).get();
    

    or, if you have a getter for the date:

    Date maxDate = list.stream().map(User::getDate).max(Date::compareTo).get();
    
    0 讨论(0)
  • 2020-12-23 19:46
    LocalDate maxDate = dates.stream()
                                .max( Comparator.comparing( LocalDate::toEpochDay ) )
                                .get();
    
    LocalDate minDate = dates.stream()
                                .min( Comparator.comparing( LocalDate::toEpochDay ) )
                                .get();
    
    0 讨论(0)
提交回复
热议问题