Here is the sample Students json
am processing
{
"students": [
{
"firstName": "Veena",
"lastName": "Butteris",
"email": "vbutteris@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-29",
"2020-06-03",
"2020-06-04",
"2020-06-05"
]
},
{
"firstName": "Edward",
"lastName": "Nogueras",
"email": "enogueras@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-26",
"2020-05-30",
"2020-05-31",
"2020-06-04",
"2020-06-05",
"2020-06-09",
"2020-06-10"
]
},
{
"firstName": "Oterman",
"lastName": "Chheang",
"email": "ochheang@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-30",
"2020-05-31",
"2020-06-01",
"2020-06-03",
"2020-06-04",
"2020-06-05",
"2020-06-06",
"2020-06-07",
"2020-06-10"
]
},
{
"firstName": "Jack",
"lastName": "Eclarinal",
"email": "jeclarinal@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-28",
"2020-05-31",
"2020-06-04",
"2020-06-05"
]
},
{
"firstName": "Cindy",
"lastName": "Macallister",
"email": "cmacallister@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-26",
"2020-06-02",
"2020-06-04",
"2020-06-05",
"2020-06-06",
"2020-06-13"
]
},
{
"firstName": "Cloe",
"lastName": "Handrick",
"email": "chandrick@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-29",
"2020-06-01",
"2020-06-04",
"2020-06-05",
"2020-06-09",
"2020-06-10"
]
},
{
"firstName": "Briane",
"lastName": "Cutchall",
"email": "bcutchall@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-29",
"2020-05-30",
"2020-05-31",
"2020-06-03",
"2020-06-04",
"2020-06-05",
"2020-06-14"
]
},
{
"firstName": "Mark",
"lastName": "Heyer",
"email": "mheyer@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-24",
"2020-05-25",
"2020-05-26",
"2020-05-29",
"2020-05-31",
"2020-06-01",
"2020-06-04",
"2020-06-05",
"2020-06-06",
"2020-06-10"
]
},
{
"firstName": "Chau",
"lastName": "Rundstrom",
"email": "crundstrom@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-26",
"2020-05-27",
"2020-05-29",
"2020-05-31",
"2020-06-02",
"2020-06-04",
"2020-06-05"
]
},
{
"firstName": "Francis",
"lastName": "Haywood",
"email": "fhaywood@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-26",
"2020-05-27",
"2020-05-29",
"2020-06-03",
"2020-06-04",
"2020-06-05",
"2020-06-09"
]
},
{
"firstName": "Maria",
"lastName": "Seiple",
"email": "mseiple@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-24",
"2020-05-25",
"2020-06-01",
"2020-06-04",
"2020-06-05",
"2020-06-06",
"2020-06-08",
"2020-06-09"
]
},
{
"firstName": "Dan",
"lastName": "Scavona",
"email": "dscavona@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-29",
"2020-06-04",
"2020-06-05",
"2020-06-07",
"2020-06-09"
]
},
{
"firstName": "Mark",
"lastName": "Kuehler",
"email": "mkuehler@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-06-01",
"2020-06-04",
"2020-06-05",
"2020-06-06",
"2020-06-09",
"2020-06-10"
]
},
{
"firstName": "Dang",
"lastName": "Come",
"email": "dcome@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-24",
"2020-05-25",
"2020-05-31",
"2020-06-04",
"2020-06-05",
"2020-06-10",
"2020-06-15"
]
},
{
"firstName": "Neha",
"lastName": "Torchia",
"email": "ntorchia@xyz.com",
"country": "Wales",
"availableDates": [
"2020-06-03",
"2020-06-06"
]
},
{
"firstName": "Anita",
"lastName": "Pujals",
"email": "apujals@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-26",
"2020-05-30",
"2020-06-01",
"2020-06-06"
]
},
{
"firstName": "Lorry",
"lastName": "Loots",
"email": "lloots@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-26",
"2020-06-01",
"2020-06-08",
"2020-06-12"
]
},
{
"firstName": "Derik",
"lastName": "Binner",
"email": "dbinner@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-26",
"2020-05-31",
"2020-06-03",
"2020-06-10"
]
},
{
"firstName": "Lasha",
"lastName": "Grybel",
"email": "lgrybel@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-26",
"2020-05-29",
"2020-06-01",
"2020-06-07",
"2020-06-10"
]
},
{
"firstName": "Bobby",
"lastName": "Shekels",
"email": "bshekels@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-26",
"2020-05-29",
"2020-05-30",
"2020-06-03",
"2020-06-06"
]
},
{
"firstName": "Linc",
"lastName": "Dorch",
"email": "ldorch@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-27",
"2020-06-01",
"2020-06-09"
]
},
{
"firstName": "Larsha",
"lastName": "Terrey",
"email": "lterrey@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-27",
"2020-05-29",
"2020-05-31",
"2020-06-06"
]
},
{
"firstName": "Dunk",
"lastName": "Dettmann",
"email": "ddettmann@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-23",
"2020-05-27",
"2020-05-31",
"2020-06-01",
"2020-06-09",
"2020-06-13"
]
},
{
"firstName": "Pearle",
"lastName": "Laker",
"email": "plaker@xyz.com",
"country": "Wales",
"availableDates": [
"2020-05-27",
"2020-05-29",
"2020-05-31",
"2020-06-03",
"2020-06-06",
"2020-06-08",
"2020-06-12"
]
},
{
"firstName": "Derek",
"lastName": "Lessenberry",
"email": "llessenberry@xyz.com",
"country": "France",
"availableDates": [
"2020-04-14",
"2020-04-15",
"2020-04-21",
"2020-04-22",
"2020-04-23",
"2020-04-24",
"2020-04-26",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Kobe",
"lastName": "Carwile",
"email": "lcarwile@xyz.com",
"country": "France",
"availableDates": [
"2020-04-21",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Judy",
"lastName": "Vala",
"email": "jvala@xyz.com",
"country": "France",
"availableDates": [
"2020-04-13",
"2020-04-15",
"2020-04-18",
"2020-04-22",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-02",
"2020-05-04",
"2020-05-06"
]
},
{
"firstName": "Rhian",
"lastName": "Hirkaler",
"email": "ghirkaler@xyz.com",
"country": "France",
"availableDates": [
"2020-04-15",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-01",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Shayna",
"lastName": "Salsberg",
"email": "msalsberg@xyz.com",
"country": "France",
"availableDates": [
"2020-04-14",
"2020-04-15",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-06"
]
},
{
"firstName": "Kate",
"lastName": "Mataalii",
"email": "smataalii@xyz.com",
"country": "France",
"availableDates": [
"2020-04-16",
"2020-04-18",
"2020-04-22",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-06"
]
},
{
"firstName": "Zidan",
"lastName": "Sefcovic",
"email": "zsefcovic@xyz.com",
"country": "France",
"availableDates": [
"2020-04-13",
"2020-04-15",
"2020-04-23",
"2020-04-24",
"2020-04-26",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-02",
"2020-05-04",
"2020-05-06",
"2020-05-07"
]
},
{
"firstName": "Mario",
"lastName": "Centner",
"email": "tcentner@xyz.com",
"country": "France",
"availableDates": [
"2020-04-13",
"2020-04-16",
"2020-04-18",
"2020-04-21",
"2020-04-23",
"2020-04-24",
"2020-04-25",
"2020-04-27",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-04",
"2020-05-06"
]
},
{
"firstName": "Nayan",
"lastName": "Mires",
"email": "jmires@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-17",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-06"
]
},
{
"firstName": "Hadiya",
"lastName": "Delsoin",
"email": "odelsoin@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Lacey",
"lastName": "Bustos",
"email": "sbustos@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-04-15",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Harrison",
"lastName": "Bugett",
"email": "sbugett@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-04-17",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-05-06"
]
},
{
"firstName": "Connor",
"lastName": "Schlembach",
"email": "lschlembach@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-13",
"2020-04-14",
"2020-04-16",
"2020-04-17",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-06"
]
},
{
"firstName": "Clarissa",
"lastName": "Stolebarger",
"email": "cstolebarger@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-04-23",
"2020-04-24",
"2020-04-28",
"2020-04-29",
"2020-04-30",
"2020-05-06"
]
},
{
"firstName": "Phoebe",
"lastName": "Mcrea",
"email": "mmcrea@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-23",
"2020-04-24",
"2020-04-26",
"2020-04-28",
"2020-04-29",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Avni",
"lastName": "Vanzant",
"email": "kvanzant@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-15",
"2020-04-26",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Fenella",
"lastName": "Daughton",
"email": "pdaughton@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-27",
"2020-05-01",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Yaqub",
"lastName": "Kokesh",
"email": "mkokesh@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-04-15",
"2020-05-01",
"2020-05-06"
]
},
{
"firstName": "Jeane",
"lastName": "Haight",
"email": "jhaight@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-13",
"2020-04-14",
"2020-04-15",
"2020-04-18",
"2020-05-06"
]
},
{
"firstName": "Grant",
"lastName": "Paleaae",
"email": "cpaleaae@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-21",
"2020-04-22",
"2020-05-01",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Sanjeev",
"lastName": "Schrupp",
"email": "rschrupp@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-14",
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Holli",
"lastName": "Bouley",
"email": "kbouley@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-26",
"2020-05-06",
"2020-05-07"
]
},
{
"firstName": "Preston",
"lastName": "Dilbeck",
"email": "ldilbeck@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-30",
"2020-05-01",
"2020-05-06"
]
},
{
"firstName": "Ceri",
"lastName": "Gruening",
"email": "dgruening@xyz.com",
"country": "Germany",
"availableDates": [
"2020-05-02",
"2020-05-06"
]
},
{
"firstName": "Shannan",
"lastName": "Purkiss",
"email": "npurkiss@xyz.com",
"country": "Germany",
"availableDates": [
"2020-04-15",
"2020-04-21",
"2020-04-22",
"2020-05-06"
]
}
]
}
The above Json has list of Students with multiple available dates for training, I need to transform the json such a way that output Json should have a list of countries with maximum Students who are available on earliest adjacent dates and produces Json as
{
"countries": [
{
"attendeeCount": 15,
"attendees": [
"llessenberry@xtz.com",
"lcarwile@xtz.com",
"jvala@xtz.com",
"ghirkaler@xtz.com",
"msalsberg@xtz.com",
"smataalii@xtz.com",
"zsefcovic@xtz.com",
"tcentner@xtz.com",
"jmires@xtz.com",
"odelsoin@xtz.com",
"sbustos@xtz.com",
"sbugett@xtz.com",
"lschlembach@xtz.com",
"cstolebarger@xtz.com",
"mmcrea@xtz.com"
],
"name": "Germany",
"startDate": "2020-04-23"
},
{
"attendeeCount": 14,
"attendees": [
"vbutteris@xtz.com",
"enogueras@xtz.com",
"ochheang@xtz.com",
"jeclarinal@xtz.com",
"cmacallister@xtz.com",
"chandrick@xtz.com",
"bcutchall@xtz.com",
"mheyer@xtz.com",
"crundstrom@xtz.com",
"fhaywood@xtz.com",
"mseiple@xtz.com",
"dscavona@xtz.com",
"mkuehler@xtz.com",
"dcome@xtz.com"
],
"name": "Wales",
"startDate": "2020-05-24"
}
]
}
Below are my DTO classes
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;
}
Below is the StudentsService class which fetcheds Students
json data and transforms it.
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;
}
}
}
My code is not performing optimal if the input json is huge like millions of students, Am wondering if the above code can be optimized any further in terms of memory consumption and to achieve less run time, please provide your valuable feedback.