#java #json #optimization #java-8
#java #json #оптимизация #java-8
Вопрос:
Вот пример Students json
обработки am https://www.npoint.io/docs/1e161b59b39401e628b2
Приведенный выше Json содержит список учащихся с несколькими доступными датами обучения, мне нужно преобразовать json таким образом, чтобы на выходе Json должен был быть список стран с максимальным количеством учащихся, которые доступны в самые ранние смежные даты, и выдает Json как https://www.npoint.io/docs/48c07ca0ee2f8bce7943
Ниже приведены мои классы DTO
public class Students {
private List<Student> Students;
//getter setter
}
public class Student {
String firstName;
String lastName;
String email;
String country;
List<String> availableDates;
}
public class CountryStudent {
private Integer count;
private List<String> attendees;
private String name;
private String startDate;
}
Ниже приведен класс StudentsService, который Students
извлекает данные json и преобразует их.
public class StudentsService{
public String processStudents(){
Students students = StudentsPayloadGenerator.getPayload(); // fetches the Students json data
Map<String,Map<String,List<String>>> countryDatesStudents = new HashMap<>();
List<Student> StudentsList = students.getStudents();
for (Student student : StudentsList){
Map<String,Integer> consecutiveDates = getConsecutiveDatesForPartner(student);
consecutiveDates.entrySet().forEach(computeStudentsAvailableOnConsecutiveDates(countryDatesStudents, student));
}
List<CountryStudent> countryStudents = new ArrayList<>();
CountriesPayload countriesPayload = new CountriesPayload();
countriesPayload.setCountries(countryStudents);
countryDatesStudents.entrySet().forEach(countryDatesPartner-> {
Map.Entry<String, List<String>> earliestAvailablePartner = countryDatesPartner.getValue().entrySet().stream().sorted((a, b) -> b.getValue().size() - a.getValue().size()).findFirst().get();
CountryStudent countryAttendee = buildCountryPayload(countryDatesPartner.getKey(), earliestAvailablePartner);
countryStudents.add(countryAttendee);
});
return getJson(countriesPayload);
}
private String getJson(CountriesPayload countriesPayload) {
ObjectMapper objectMapper = new ObjectMapper();
String countriesPayloadJson = null;
try {
countriesPayloadJson = objectMapper.writeValueAsString(countriesPayload);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return countriesPayloadJson;
}
private CountryStudent buildCountryPayload(String country, Map.Entry<String, List<String>> attendeesEntry) {
String adjacentDatePair = attendeesEntry.getKey();
String earliestDate = adjacentDatePair.substring(0,adjacentDatePair.indexOf("_"));
CountryStudent countryAttendee = new CountryStudent();
countryAttendee.setName(country);
countryAttendee.setAttendeeCount(attendeesEntry.getValue().size());
countryAttendee.setAttendees(attendeesEntry.getValue());
countryAttendee.setStartDate(earliestDate);
return countryAttendee;
}
private Consumer<Map.Entry<String, Integer>> computeStudentsAvailableOnConsecutiveDates(Map<String, Map<String, List<String>>> countryDatesStudents, Student partner) {
return entry -> {
countryDatesStudents.computeIfAbsent(partner.getCountry(), v -> new TreeMap<String, List<String>>());
Map<String, List<String>> datesStudents = countryDatesStudents.get(partner.getCountry());
datesStudents.computeIfAbsent(entry.getKey(), v -> new ArrayList<>());
datesStudents.get(entry.getKey()).add(partner.getEmail());
};
}
private Map<String, Integer> getConsecutiveDatesForPartner(Student partner) {
Map<String,Integer> consecutiveDates = new TreeMap<>();
List<LocalDate> availableDates = partner.getAvailableDates().stream().map(this::convertToLocalDate).collect(Collectors.toList());
Collections.sort(availableDates,(a,b) ->{
if(a.isAfter(b)) return 1;
else if(a.isBefore(b)) return -1;
else return 0;
});
tupleIterator(availableDates, (date1, date2) -> {
if(isConsecutive(date1,date2))
consecutiveDates.put(date1 "_" date2,1);
});
return consecutiveDates;
}
private LocalDate convertToLocalDate(String date){
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-d");
return LocalDate.parse(date, formatter);
}
private boolean isConsecutive(LocalDate date1, LocalDate date2) {
return DAYS.between(date1,date2) == 1;
}
public static <T> void tupleIterator(Iterable<T> iterable, BiConsumer<T, T> consumer) {
Iterator<T> it = iterable.iterator();
if(!it.hasNext()) return;
T first = it.next();
while(it.hasNext()) {
T next = it.next();
consumer.accept(first, next);
first = next;
}
}
}
Мне интересно, можно ли оптимизировать приведенный выше код дальше, пожалуйста, предоставьте свои ценные отзывы.
Комментарии:
1. Ну, вещи, связанные с этим
Map<String,Map<String,List<String>>>
, должны быть оптимизированы, на мой взгляд…2. Не могли бы вы также опубликовать ожидаемый результат JSON?
3. Это было бы более подходящим для codereview.stackexchange.com
4. @LHCHIN Вот ожидаемый результат npoint.io/docs/48c07ca0ee2f8bce7943