枚举与Lambda的结合 实现可读性良好的策略模式
枚举类:
1.枚举类很安全,不能被实例化对象,甚至用反射都无法创建对象;
2.可以使用name()和oridnal()方法来返回枚举对象的实例名称和序数(从0开始);
3.所有的枚举类都有静态方法:values可以获取当前枚举类中的所有实例;
4.所有的枚举类都有静态方法:valuesOf可以将String类型的字符串转换为枚举类型的对象;
5.枚举常量必须最先声明,并且常量之间需要用逗号隔开,最后一个常量用分号;
6.枚举常量之后若使用{},则表示当前枚举类的匿名内部类;
7.使用switch操作枚举。
策略模式:
1.定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换;
2.在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护;
3.一个系统有许多许多类,而区分它们的只是他们直接的行为;
4.在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。
案例需求:
1.一个班级(SchoolClass)有名字(String)、有很多学生(List<Student>)、和语数外三个课代表(List<Representative>);
2.有了学生List<Student>、和课代表List<Representative>,需要生成班级(SchoolClass)实例,
解决方案:
使用枚举来找到具体的课代表并赋给班级(SchoolClass)实例
Main方法调用:LambdaEnum
public class LambdaEnum {
private static List<Student> classOneStudents = new ArrayList<>();
private static List<Representative> representatives = new ArrayList<>();
static {
classOneStudents.add(new Student("Weison",5,"男",90,2));
classOneStudents.add(new Student("Evan",5,"女",60,1));
classOneStudents.add(new Student("Jack",5,"男",90,3));
classOneStudents.add(new Student("Luis",5,"男",60,3));
classOneStudents.add(new Student("Elen",5,"女",90,5));
classOneStudents.add(new Student("Obam",5,"男",70,1));
classOneStudents.add(new Student("Bush",5,"女",90,1));
ChineseRepresentative chineseRepresentative =
new ChineseRepresentative("Evan", 6, "女", 80, 2);
MathematicsRepresentative mathematicsRepresentative =
new MathematicsRepresentative("Jack", 7, "男", 70, 2);
EnglishRepresentative englishRepresentative =
new EnglishRepresentative("Luis", 8, "女", 60, 4);
representatives.add(chineseRepresentative);
representatives.add(mathematicsRepresentative);
representatives.add(englishRepresentative);
}
public static void main(String[] args) {
SchoolClass classOne = SchoolClass.builder()
.className("classOne").students(classOneStudents).build();
representatives.stream()
.forEach(representative ->
RepresentativeEnum.getSchoolClass(representative)
.apply(classOne, representative));
System.out.println("----->" + classOne);
}
}
执行结果:
----->
SchoolClass{
className='classOne',
students=[
Student{name='Weison', age=5, sex='男', score=90, citationCount=2},
Student{name='Evan', age=5, sex='女', score=60, citationCount=1},
Student{name='Jack', age=5, sex='男', score=90, citationCount=3},
Student{name='Luis', age=5, sex='男', score=60, citationCount=3},
Student{name='Elen', age=5, sex='女', score=90, citationCount=5},
Student{name='Obam', age=5, sex='男', score=70, citationCount=1},
Student{name='Bush', age=5, sex='女', score=90, citationCount=1}],
chineseRepresentative=ChineseRepresentative{name='Evan', age=6, sex='女', score=80, citationCount=2},
englishRepresentative=EnglishRepresentative{name='Luis', age=8, sex='女', score=60, citationCount=4},
mathematicsRepresentative=MathematicsRepresentative{name='Jack', age=7, sex='男', score=70, citationCount=2}
}
学生:Student
@Data
@NoArgsConstructor
public class Student implements Comparable<Student> {
String name;
Integer age;
String sex;
Integer score;
Integer citationCount;
public Student(String name, Integer age, String sex, Integer score, Integer citationCount) {
this.name = name;
this.age = age;
this.sex = sex;
this.score = score;
this.citationCount = citationCount;
}
public int compareTo(Student student) {
if (this.age >= student.age)
return 1;
return -1;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", score=" + score +
", citationCount=" + citationCount +
'}';
}
}
课代表抽象类:Representative
public abstract class Representative extends Student {
private String subject;
public Representative(String name, Integer age, String sex, Integer score, Integer citationCount, String subject) {
super(name, age, sex, score, citationCount);
this.subject = subject;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
}
语文课代表:ChineseRepresentative
public class ChineseRepresentative extends Representative {
public ChineseRepresentative(String name, Integer age, String sex, Integer score, Integer citationCount) {
super(name, age, sex, score, citationCount, "语文");
}
@Override
public String toString() {
return "ChineseRepresentative{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", score=" + score +
", citationCount=" + citationCount +
'}';
}
}
英语课代表:EnglishRepresentative
public class EnglishRepresentative extends Representative {
public EnglishRepresentative(String name, Integer age, String sex, Integer score, Integer citationCount) {
super(name, age, sex, score, citationCount, "英语");
}
@Override
public String toString() {
return "EnglishRepresentative{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", score=" + score +
", citationCount=" + citationCount +
'}';
}
}
数学课代表:MathematicsRepresentative
public class MathematicsRepresentative extends Representative {
public MathematicsRepresentative(String name, Integer age, String sex, Integer score, Integer citationCount) {
super(name, age, sex, score, citationCount, "数学");
}
@Override
public String toString() {
return "MathematicsRepresentative{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", score=" + score +
", citationCount=" + citationCount +
'}';
}
}
班级:SchoolClass
@Data
@Builder
public class SchoolClass {
private String className;
private List<Student> students;
private ChineseRepresentative chineseRepresentative;
private EnglishRepresentative englishRepresentative;
private MathematicsRepresentative mathematicsRepresentative;
@Override
public String toString() {
return "SchoolClass{" +
"className='" + className + '\'' +
", students=" + students +
", chineseRepresentative=" + chineseRepresentative +
", englishRepresentative=" + englishRepresentative +
", mathematicsRepresentative=" + mathematicsRepresentative +
'}';
}
}
课代表枚举:RepresentativeEnum ->用来找到是哪个课代表
public enum RepresentativeEnum {
CHINESEREPRESENTATIVES("语文", (schoolClass, representative) -> {
ChineseRepresentative chineseRepresentative = (ChineseRepresentative) representative;
schoolClass.setChineseRepresentative(chineseRepresentative);
return schoolClass;
}),
ENGLISHREPRESENTATIVES("英语", (schoolClass, representative) -> {
EnglishRepresentative englishRepresentative = (EnglishRepresentative) representative;
schoolClass.setEnglishRepresentative(englishRepresentative);
return schoolClass;
}),
MATHEMATICSREPRESENTATIVES("数学", (schoolClass, representative) -> {
MathematicsRepresentative mathematicsRepresentative = (MathematicsRepresentative) representative;
schoolClass.setMathematicsRepresentative(mathematicsRepresentative);
return schoolClass;
});
private String representativeVal;
private BiFunction<SchoolClass, Representative, SchoolClass> schoolClassBiFunction;
RepresentativeEnum(String representativeVal, BiFunction<SchoolClass,
Representative, SchoolClass> schoolClassBiFunction) {
this.representativeVal = representativeVal;
this.schoolClassBiFunction = schoolClassBiFunction;
}
public static BiFunction<SchoolClass, Representative, SchoolClass> getSchoolClass(
Representative representative) {
return Arrays.stream(RepresentativeEnum.values())
.filter(representativeEnum -> representativeEnum.representativeVal
.equals(representative.getSubject()))
.map(representativeEnum -> representativeEnum.schoolClassBiFunction)
.findFirst()
.orElse(null);
}
}