gpt4 book ai didi

java - 使用 Collection 框架计算值(value)的百分比

转载 作者:行者123 更新时间:2023-12-01 10:22:02 25 4
gpt4 key购买 nike

我有 的列表培训申请 其中每个元素都有 的列表意见反馈 .

@Data
class TrainingRequest{
@Transient
List<Feedack> feedback;
}

@Data
class Feedback{
String Q1;
String Q2;
}
我需要获得 Q1、Q2 的所有给定结果并计算每个值的百分比。
List<TrainingRequest> trainingList = Optional.ofNullable(trainingRequestList).orElseGet(Collections::emptyList)
.stream().map(m -> {
List<Feedback> feedback = findByTrainingRequestId(m.getId());
m.setFeedback(feedback); // assigning Feedack to TrainingRequest
return m;
}).collect(Collectors.toList());
平息所有反馈
List<Feedback> flatMap = trainingList.stream().flatMap(f -> f.getFeedback().stream()).collect(Collectors.toList());
为了计算 Q1 和 Q2 的每个值,我将其分组并得到计数。我需要获得计数的每个 Q1、Q2 值的百分比。
Map<String, Map<String, Long>> map = new TreeMap<>();

map.put("Q1", flatMap.stream().collect(Collectors.groupingBy(Feedback::getQ1, Collectors.counting())));
map.put("Q2", flatMap.stream().collect(Collectors.groupingBy(Feedback::getQ2, Collectors.counting())));
当我使用 Collectors.counting() ,它给出了以下输出:
{
"Q1": {
"unsatisfied": 2,
"Satisfied": 1,
"satisfied": 1
},
"Q2": {
"Yes": 4
}
}
但我需要它按照我的预期给出百分比
{
"Q1": {
"unsatisfied": 50 %,
"Satisfied": 25 %,
"satisfied": 25 %
},
"Q2": {
"Yes": 100 %
}
}
如何以有效的方式做到这一点?我需要优化上面的代码吗?

最佳答案

你的问题有点不清楚,所以我试着为自己简化一下逻辑。我想出了一个 snipit 来计算 IntStream 中偶数/奇数整数的百分比(这与您尝试做的事情没有太大不同)。

IntStream.range(0, 101).boxed()
.collect(Collectors.groupingBy(integer -> (integer % 2) == 0 ? "even" : "odd",
Collectors.collectingAndThen(Collectors.counting(), aLong -> aLong + " %")));

注意 collectingAndThen() 的使用这让我们先来 collect值,然后使用 mapper/finisher 将结果映射到另一个值.

在你的情况下,这将被翻译成这样的

map.put("Q1", flatMap.stream().collect(Collectors.groupingBy(Feedback::getQ1,
Collectors.collectingAndThen(Collectors.counting(), count -> (count / flatMap.size()) * 100.00 + " %")));

map.put("Q2", flatMap.stream().collect(Collectors.groupingBy(Feedback::getQ2,
Collectors.collectingAndThen(Collectors.counting(), count -> (count / flatMap.size()) * 100.00 + " %")));

更新

由于您专门询问了优化问题,因此这里有几点说明

1.当你可以重用现有的集合时,不要创建一个新的集合

// this code is unnecessarily creating a new collection
List<TrainingRequest> trainingList = Optional.of(trainingRequestList).orElseGet(Collections::emptyList)
.stream().map(m -> {
List<Feedback> feedback = findByTrainingRequestId(m.getId());
m.setFeedback(feedback); // assigning Feedack to TrainingRequest
return m;
}).collect(Collectors.toList());

可以简化成这样

// to avoid NullPointerExceptions
trainingRequestList = trainingRequestList == null ? Collections.emptyList() : trainingRequestList;
// because java is pass by reference we are able to do this
trainingRequestList.forEach(m -> m.setFeedback(findByTrainingRequestId(m.getId())));

2.如果您要再次流式传输 Collection ,请不要 Collection

// to hold the count of Q1 an Q2
final Map<String, Integer> count = new HashMap<>();

// Order(n), n = trainingRequests count
trainingRequestList.forEach(trainingRequest -> {
List<Feedback> feedbacks = findByTrainingRequestId(trainingRequest.getId());
// Order(m), m = feedbacks count
feedbacks.forEach(f -> {
count.merge("Q1", f.getQ1(), Integer::sum);
count.merge("Q2", f.getQ2(), Integer::sum);
});
trainingRequest.setFeedback(feedbacks);
}

// finally we can collect the percentage
// Order(1)
int totalCountOfFeedbacks = count.values().stream().mapToInt(Integer::intValue).sum();
Map<String, String> result = count.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> 100.00 * (entry.getValue() / totalCountOfFeedbacks ) + " %"));

请注意,这些优化不会影响您的逻辑当前为 Order(n * m) 的事实。 ,如果不实际查看代码,很难为您提供进一步的提示。

关于java - 使用 Collection 框架计算值(value)的百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61387667/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com