我有一个方法可以遍历部门中的Lectors(基本上是用户),并返回一个整数的JSON,该整数表示将哪个讲师分配给哪个程度(程度是一个枚举)
我在这里有方法:
@Override
public String getDepartmentStatistics(String departmentName) {
List<Lector> lectorList = departmentRepository.getByName(departmentName).getLector();
int assistantNumbers = 0;
int associate_professorNumbers = 0;
int professorNumbers = 0;
for (Lector lector : lectorList) {
if (lector.getLectorDegree().equals(ASSISTANT)) {
assistantNumbers += 1;
} else if (lector.getLectorDegree().equals(ASSOCIATE_PROFESSOR)) {
associate_professorNumbers += 1;
} else if (lector.getLectorDegree().equals(PROFESSOR)) {
professorNumbers += 1;
} else {
return null;
}
}
return String.valueOf(new JSONObject()
.put("Assistants", assistantNumbers)
.put("Associate professors", associate_professorNumbers)
.put("Professors", professorNumbers));
}
它按预期工作。
我的问题是如何改善其质量/外观?
答案 0 :(得分:3)
您可以使用switch
语句来检查度数,而不是多个if
:
@Override
public String getDepartmentStatistics(String departmentName) {
List<Lector> lectorList = departmentRepository.getByName(departmentName).getLector();
int assistantNumbers = 0;
int associate_professorNumbers = 0;
int professorNumbers = 0;
for (Lector lector : lectorList) {
switch(lector.getLectorDegree()) {
case ASSISTANT:
assistantNumbers += 1;
break;
case ASSOCIATE_PROFESSOR:
associate_professorNumbers += 1;
break;
case ASSISTANT:
professorNumbers += 1;
break;
default:
return null;
}
}
return String.valueOf(new JSONObject()
.put("Assistants", assistantNumbers)
.put("Associate professors", associate_professorNumbers)
.put("Professors", professorNumbers));
}
答案 1 :(得分:2)
下面是一个使用Map
来跟踪所有计数的示例:
enum Degree {
PROFESSOR,
ASSISTANT,
ASSOCIATE_PROFESSOR
}
class Lector {
Degree degree;
public Degree getDegree() {
return degree;
}
}
public String getDepartmentStatistics(String departmentName) {
List<Lector> lectorList = /*...*/
Map<Degree, Integer> result = new EnumMap<>(Degree.class);
lectorList.stream()
.map(Lector::getDegree)
.forEach(degree -> {
Integer currentCount = result.getOrDefault(degree, 0);
result.put(degree, ++currentCount);
});
return String.valueOf(new JSONObject()
.put("Assistants", result.getOrDefault(Degree.ASSISTANT, 0))
.put("Associate professors", result.getOrDefault(Degree.ASSOCIATE_PROFESSOR, 0))
.put("Professors", result.getOrDefault(Degree.PROFESSOR, 0)));
}
您也可以通过流来代替Stream.forEach
进行分组。您也可以使用Map.compute
代替getOrDefault
。这个版本是我主观上首选的解决方案,因为它可以很清楚地了解正在发生的事情。
与使用if
或switch
相比,新的Degree
值是开箱即用的(只有return语句不是通用的,但也可以泛化)。
编辑:安迪·特纳(Andy Turner)指出,使用Map.merge
改进了解决方案:
public String getDepartmentStatistics(String departmentName) {
List<Lector> lectorList = /*...*/
Map<Degree, Integer> result = new EnumMap<>(Degree.class);
lectorList.stream()
.map(Lector::getDegree)
.forEach(degree -> result.merge(degree, 1, Integer::sum));
return String.valueOf(new JSONObject()
.put("Assistants", result.getOrDefault(Degree.ASSISTANT, 0))
.put("Associate professors", result.getOrDefault(Degree.ASSOCIATE_PROFESSOR, 0))
.put("Professors", result.getOrDefault(Degree.PROFESSOR, 0)));
}
EDIT2: 让我包括一个完全功能性的方法,该方法不会将命令性方法和功能性方法混合使用过多(如评论中所述):
public String getDepartmentStatistics(String departmentName) {
List<Lector> lectorList = /*...*/
Map<Degree, Integer> result =
lectorList.stream()
.collect(Collectors.groupingBy(
Lector::getDegree,
() -> new EnumMap<>(Degree.class),
Collectors.counting()
));
return String.valueOf(new JSONObject()
.put("Assistants", result.getOrDefault(Degree.ASSISTANT, 0))
.put("Associate professors", result.getOrDefault(Degree.ASSOCIATE_PROFESSOR, 0))
.put("Professors", result.getOrDefault(Degree.PROFESSOR, 0)));
}
答案 2 :(得分:0)
考虑用策略或访问者列表替换if(或switch)语句 (我不确定在这种情况下哪个名称适用)。
这是一些示例代码(注意:我没有尝试编译此代码):
public enum LectorDegreeType
{
ASSISTANT("Assistants"),
ASSOCIATE_PROFESSOR("Associate Professors"),
PROFESSOR("Professor");
private final title;
LectorDegreeType(final String titleValue)
{
title = titleValue;
}
public String getTitle()
{
return title;
}
}
public interface LectorBlammy
{
void blam(@NotNull Lector lector);
void retrieveTitle();
void retrieveTotal();
}
public abstract class AbstractLectorBlammy
implements LectorBlammy
{
private final LectorDegreeType desiredDegree;
private int matchCount;
protected AbstractLectorBlammy(
@NotNull final LectorDegreeType desiredDegreeValue)
{
desiredDegree = Objects.requireNotNull(desiredDegreeValue);
matchCount = 0;
}
// perhaps make this a final method.
public void blam(@NotNull final Lector lector)
{
if (lector.getLectorDegree().equals(desiredDegree))
{
++matchCount;
}
}
public void retrieveTitle()
{
return desiredDegree.getTitle();
}
public void retrieveTotal()
{
return matchCount;
}
}
public class LectorBlammyAssistant
extends AbstractLectorBlammy
{
public LectorBlammyAssistant()
{
AbstractLectorBlammy(LectorDegreeType.ASSISTANT);
}
}
public class LectorBlammyAssociateProfessor
extends AbstractLectorBlammy
{
public LectorBlammyAssistant()
{
AbstractLectorBlammy(LectorDegreeType.ASSOCIATE_PROFESSOR);
}
}
public class LectorBlammyProfessor
extends AbstractLectorBlammy
{
public LectorBlammyAssistant()
{
AbstractLectorBlammy(LectorDegreeType.PROFESSOR);
}
}