I have an object Officer
public class Officer {
private String name;
private int totalDaysInOffice;
public Officer(String name, int totalDaysInOffice) {
this.name = name;
this.totalDaysInOffice = totalDaysInOffice;
}
@Override
public String toString() {
return "Officer{" +
"name='" + name + '\'' +
", totalDaysInOffice=" + totalDaysInOffice +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTotalDaysInOffice() {
return totalDaysInOffice;
}
public void setTotalDaysInOffice(int totalDaysInOffice) {
this.totalDaysInOffice = totalDaysInOffice;
}
}
Here each officer have spent days in office(just made up variable).
What I want to do is the divide the officers once I have the sum of days 10000 in separate list
Based on example below , I want to have list with
one list with John , Matthew , and Robert since they sum to more 10K
One list with Patrick as he has 10K
Dave would be in separate list.
I have tried group by but not sure how can I add this condition.
public class OffierExample {
public static void main(String[] args) {
List<Officer> officerList = new ArrayList<>();
officerList.add(new Officer("John",5000));
officerList.add(new Officer("Matthew",3000));
officerList.add(new Officer("Robert",2000));
officerList.add(new Officer("Dave",2000));
officerList.add(new Officer("Patrick",10000));
Map<Officer, Integer> collect = officerList.stream().collect(Collectors.groupingBy(o -> o, Collectors.summingInt(Officer::getTotalDaysInOffice)));
System.out.println(collect);
}
}
Is there anyways it can be done in Java 8
**
**
I have achieved using traditional loop but I want to use Java 8 group by if possible
public class OffierExample {
public static void main(String[] args) {
List<Officer> officerList = new ArrayList<>();
officerList.add(new Officer("John", 5000));
officerList.add(new Officer("Matthew", 3000));
officerList.add(new Officer("Robert", 2000));
officerList.add(new Officer("Dave", 2000));
officerList.add(new Officer("Patrick", 10000));
officerList.add(new Officer("YYYY", 600));
officerList.add(new Officer("XXXX", 600));
//keep totalDaysInOfficeSum
int totalDaysInOfficeSum = 0;
//the final list
List<List<Officer>> off = Lists.newArrayList();
//the working list
List<Officer> tempOffList = Lists.newArrayList();
for (Officer officer : officerList) {
//get sum
totalDaysInOfficeSum = totalDaysInOfficeSum + officer.getTotalDaysInOffice();
//if sum is more than 10K or equal
if (totalDaysInOfficeSum >= 10000) {
//add it in temp list
tempOffList.add(officer);
//add in master list
off.add(tempOffList);
//reset temp list
tempOffList = new ArrayList<>();
//reset sum
totalDaysInOfficeSum = 0;
continue;
}
//add in temp list
tempOffList.add(officer);
}
//any left over
if (!tempOffList.isEmpty()) {
off.add(tempOffList);
}
//printint out
System.out.println("Officers list =" + off.size());
off.forEach(o -> {
System.out.println("List size:" + o.size());
o.forEach(oo -> {
System.out.println(oo.getName() + "::" + oo.getTotalDaysInOffice());
});
System.out.println("====================");
});
}
}
Output
Officers list =3
List size:3
John::5000
Matthew::3000
Robert::2000
====================
List size:2
Dave::2000
Patrick::10000
====================
List size:2
YYYY::600
XXXX::600
====================
Something like this:
List<List<Officer>> result = officerList.stream().collect(Collector.of(
() -> new ArrayList<List<Officer>>(),
(list, entry) -> {
if (list.size() == 0) {
List<Officer> inner = new ArrayList<>();
inner.add(entry);
list.add(inner);
} else {
List<Officer> last = list.get(list.size() - 1);
int sum = last.stream().mapToInt(Officer::getTotalDaysInOffice).sum();
if (sum < 10_000) {
last.add(entry);
} else {
List<Officer> inner = new ArrayList<>();
inner.add(entry);
list.add(inner);
}
}
},
(left, right) -> {
throw new IllegalArgumentException("Not for parallel");
}));