Как получить последнюю запись из ArrayList на основе даты - PullRequest
2 голосов
/ 24 октября 2019

У меня есть список записей, как показано ниже. Я хочу получить последнюю запись, основанную на дате, и установить ее имя как «H». Таким же образом я хочу установить 'L' в качестве имени для всех оставшихся записей.

List<Student> studentList = new ArrayList<>();

try {
  studentList.add(new Student("A", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-1990")));
  studentList.add(new Student("B", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2010")));
  studentList.add(new Student("C", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2011")));
  studentList.add(new Student("D", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2012")));
  studentList.add(new Student("E", new SimpleDateFormat("dd-MM-yyyy").parse("01-01-2018")));

} catch (ParseException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();  
}

Student student = Collections.max(studentList, Comparator.comparing(s -> s.getDate()));

Я пробовал как выше, но здесь я могу установить имя только для последней записи, но я не могу установить имя для всех остальных оставшихся записей.

Любая помощь будет оценена.

Ответы [ 3 ]

3 голосов
/ 24 октября 2019

Однопоточная версия:

// Find the latest student in the list 
Student latest = Collections.max(studentList,
                                 Comparator.comparing(s -> s.getDate()));

// Iterate the list, setting each student's name depending on whether it
// is the latest or not. 
studentList.forEach(s -> {s.setName(s == latest ? "H" : "L");});

Приведенный выше код выполняет два прохода по списку. Есть и другие способы сделать второй шаг;например,

studentList.forEach(s -> {s.setName("L");});
latest.setName("H");

Вызов max вызовет NoSuchElementException, если коллекция пуста. Вы можете рассматривать это как ошибку (т.е. позволить распространению исключения) или проверить пустой список перед началом работы.


Возможно одноразовое решение с использованием потоков:

Optional<Student> latest = studentList.stream()
                .peek(s -> {s.setName("L")})
                .max(Comparator.comparing(s -> s.getDate());
latest.ifPresent(s -> {s.setName("H")});

Мы устанавливаем имя каждого студента на "L" и находим последнее за один проход. Затем мы сбрасываем имя последнего студента на "H".

Эта версия также работает для пустого списка. (Действительно, нам нужно было бы потрудиться, чтобы это не сработало. Optional полезно в некоторых контекстах.)

Если список был достаточно длинным, возможно, стоит использовать parallel().

2 голосов
/ 24 октября 2019

Если у вас есть только дата, пожалуйста, используйте LocalDate и DateTimeFormatter из java-8

studentList.add(new Student("A", LocalDate.parse("01-01-1990", DateTimeFormatter.ofPattern("dd-MM-yyyy")));

Так что класс Student будет

public class Student {

    private String name;
    private date LocalDate;

    //getters and setters

   }

Теперь используйте Collections.max Поскольку LocalDate реализует Comparable

Student student =  Collections.max(studentList, Comparator.comparing(s -> s.getDate()));

Для установки H и L

1-й доступ

Подход, который я бы предложил здесь, это сначала установить name = L для каждого студента, использующего forEach

studentList.forEcah(stu->stu.setName("L"));

Теперь просто получите максимальный ученик, используя компаратор и установите имя = H

Student student =  Collections.max(studentList, Comparator.comparing(s -> s.getDate()));
student.setName("H");

2-й подход

Вы можете отсортировать List сначала

studentList.sort(Comparator.comparing(s -> s.getDate()).reversed());

И затем установить имя = H для первой записи и L для остальных

IntStream.range(0,studentList.size())
         .forEach(i->{
              if(i==0) {
                 studentList.get(i).setName("H");
                }
                else {
               studentList.get(i).setName("L");
               }
             });
0 голосов
/ 24 октября 2019

Просто переберите свой список и задайте нужное имя:

Student student = Collections.max(studentList, Comparator.comparing(Student::getDate));
studentList.forEach(s -> s.name = s.equals(student) ? "H" : "L");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...