'Count the total boolean value of true using Java 8
Im using java 8. I have a class Operator
which has 3 fields.
class Operator{
private String type;
private boolean updateRequested;
private boolean deleteRequested;
}
I have list of Operator
. I just want to count the updatedRequested
and deleteRequested
based on type
whose value is true
and add into the Map which is Map<String,Result>
class Result{
private int deleteReqCount;
private int updateReqCount;
}
Expected result
{
"Cricket":{ deleteReqCount:10, updateReqCount:0}, // count only the value == `true`
"Football":{ deleteReqCount:2, updateReqCount:10}, // count only the value == `true`
}
This question is bit simple and I did using for loops and if condition. But I'm impressed with Stream apis and Collectors framework. I'm a beginner, so tried list.stream().collect(Collectors.groupingBy(g -> g.getType()));
but couldn't go further.
Thanks in advance
Solution 1:[1]
Here is an implementation using Collectors.toMap
class Operator {
public String type;
public boolean updateRequested;
public boolean deleteRequested;
Operator(String type, boolean updateRequested, boolean deleteRequested) {
this.type = type;
this.updateRequested = updateRequested;
this.deleteRequested = deleteRequested;
}
}
class Result {
public int deleteReqCount;
public int updateReqCount;
Result(int deleteReqCount, int updateReqCount) {
this.deleteReqCount = deleteReqCount;
this.updateReqCount = updateReqCount;
}
@Override
public String toString() {
return "Result{" +
"deleteReqCount=" + deleteReqCount +
", updateReqCount=" + updateReqCount +
'}';
}
}
Map<String, Result> solve(List<Operator> operatorList) {
return operatorList.stream()
.collect(Collectors.toMap(
v -> v.type,
v -> new Result(v.deleteRequested ? 1 : 0, v.updateRequested ? 1 : 0),
(result, result2) -> {
int deleteReqCount = result.deleteReqCount + result2.deleteReqCount;
int updateReqCount = result.updateReqCount + result2.updateReqCount;
return new Result(deleteReqCount, updateReqCount);
}
));
}
List<Operator> operatorList = Arrays.asList(
new Operator("cricket", true, true),
new Operator("cricket", true, false),
new Operator("cricket", true, true),
new Operator("soccer", false, true),
new Operator("soccer", true, true)
);
System.out.println(solve(operatorList));
Output:
{soccer=Result{deleteReqCount=2, updateReqCount=1}, cricket=Result{deleteReqCount=2, updateReqCount=3}}
Solution 2:[2]
An update to Sai Kiran's excellent answer:
Map<String, Result> solve(List<Operator> operatorList) {
return operatorList.stream()
.collect(Collectors.toMap(
v -> v.type,
v -> new Result(v.deleteRequested ? 1 : 0, v.updateRequested ? 1 : 0),
(result, result2) -> {
result.updateReqCount += result2.updateReqCount;
result.deleteReqCount += result2.deleteReqCount;
return result;
}
));
}
Solution 3:[3]
As per comment by @Andreas,
operators.stream().collect(Collectors.toMap(
Operator::getType,
v -> new Result(v.isDeleteRequested() ? 1 : 0, v.isUpdateRequested() ? 1 : 0),
Result::merge
));
Merge method,
public Result merge(Result result) {
this.updateReqCount+=result.updateReqCount;
this.deleteReqCount+=result.deleteReqCount;
return this;
}
Solution 4:[4]
For the time when you update to Java 12 or higher, the task can be achieved using Collectors.teeing
:
List<Operator> ops = //your operators list
Map<String, Result> myMap =
ops.stream()
.collect(
Collectors.groupingBy(Operator::getType,
Collectors.teeing(
Collectors.filtering(Operator::isUpdateRequested,Collectors.counting()),
Collectors.filtering(Operator::isDeleteRequested,Collectors.counting()),
(updateCount, deleteCount) -> {
return new Result(updateCount.intValue(),deleteCount.intValue());
}
)));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sai Kiran |
Solution 2 | K.Nicholas |
Solution 3 | Vikas Yadav |
Solution 4 | Eritrean |