Java 8 Оптимизирует код для преобразования структуры Json

#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