private int age;
private double salary;
//空参,全参构造器
//getter,setter方法
//重写hashcode(),equals(),toString()方法
}
然后在集合内添加相应的员工:
List emps = Arrays.asList(
new Employee(101, “张三”, 18, 9999.99),
new Employee(102, “李四”, 59, 6666.66),
new Employee(103, “王五”, 28, 3333.33),
new Employee(104, “赵六”, 8, 7777.77),
new Employee(105, “田七”, 38, 5555.55)
);
2.1 案例需求1:获取年龄小于35的员工信息
public List filterEmployeeAge(List emps){
List list = new ArrayList<>();
for (Employee emp : emps) {
if(emp.getAge() <= 35){
list.add(emp);
}
}
return list;
}
这是过滤年龄的方法,传入一个元素都是员工的集合,会得到筛选条件为年龄小于等于35的员工集合。
我们可以对filterEmployeeAge方法进行测试。
@Test
public void test3(){
List list = filterEmployeeAge(emps);
for (Employee employee : list) {
System.out.println(employee);
}
}
输出结果如下:
2.2 案例需求2:获取工资大于5000的员工信息
可以仿照filterEmployeeAge方法再写一个按照工资过滤的方法filterEmployeeSalary
public List filterEmployeeSalary(List emps){
List list = new ArrayList<>();
for (Employee emp : emps) {
if(emp.getSalary() >= 5000){
list.add(emp);
}
}
return list;
}
对比filterEmployeeAge和filterEmployeeSalary方法,可以发现这两个过滤方法的代码主要区别就是if()里面的判断条件,符合相应条件的加入集合。如果还有其它的需求:例如姓名长度,性别,部门,工资小于3500,年龄大于60等过滤条件,我们还得再写相应的方法;而这些方法的区别仍是if()里面的判断条件,我们却得写很多重复的代码,增大很多不必要的工作量。
说到这里,很多人就会想到了策略模式就是解决这个问题的。(接下来使用策略模式优化上面的代码,顺便复习一下策略设计模式)
2.3 优化方式1:策略设计模式
将if()里面的判断条件抽取出来作为一个接口。
public interface MyPredicate {
public boolean test(T t);
}
然后,不同的过滤条件封装在MyPredicate接口的实现类中
按年龄过滤条件实现类:
public class FilterEmployeeForAge implements MyPredicate{
@Override
public boolean test(Employee t) {
return t.getAge() <= 35;
}
}
按工资过滤条件实现类:
public class FilterEmployeeForSalary implements MyPredicate {
@Override
public boolean test(Employee t) {
return t.getSalary() >= 5000;
}
}
针对接口写统一的过滤员工方法,不同的过滤条件只需要传入相应的MyPredicate接口实现类即可以。
public List filterEmployee(List emps, MyPredicate mp){
List list = new ArrayList<>();
for (Employee employee : emps) {
if(mp.test(employee)){
list.add(employee);
}
}
return list;
}
测试:
@Test
public void test4(){
List list = filterEmployee(emps, new FilterEmployeeForAge());
for (Employee employee : list) {
System.out.println(employee);
}
System.out.println(“------------------------------------------”);
List list2 = filterEmployee(emps, new FilterEmployeeForSalary());
for (Employee employee : list2) {
System.out.println(employee);
}
}
2.4 优化方式2:匿名内部类
事实上,我们在使用策略模式进行优化的时候,并不会写MyPredicate接口的实现类,而是将MyPredicate接口的匿名内部类作为参数传入filterEmployee方法。
//优化方式二:匿名内部类
@Test
public void test5(){
List list = filterEmployee(emps, new MyPredicate() {
@Override
public boolean test(Employee t) {
return t.getId() <= 3;
}
});
for (Employee employee : list) {
System.out.println(employee);
}
}
2.5 优化方式3:Lambda表达式
说到匿名内部类作为参数传递给方法,就离Lambda表达式非常接近了。Lambda表达式就是对匿名内部类作为参数传递给方法进行优化。
这里先直接给出Lambda表达式优化后的结果,大家可以感受下代码是多么的简洁。
//优化方式三:Lambda 表达式
@Test
public void test6(){
List list = filterEmployee(emps, (e) -> e.getAge() <= 35);
list.forEach(System.out::println);
System.out.println(“------------------------------------------”);
List list2 = filterEmployee(emps, (e) -> e.getSalary() >= 5000);
list2.forEach(System.out::println);
}
2.6 优化方式4:Stream API
这里也是直接给出结果,后续解释。
//优化方式四:Stream API
@Test
public void test7(){
//年龄小于等于35的员工信息
emps.stream()
.filter((e) -> e.getAge() <= 35)
.forEach(System.out::println);
}
三 Lambda表达式语法
=============
Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。
箭头操作符的左侧传递给接口内抽象方法的形参,箭头操作符右侧作为接口内抽象方法的方法体。
3.1 语法:
Lambda 表达式的基础语法:Java8中引入了一个新的操作符 “->” 该操作符称为箭头操作符或 Lambda 操作符
箭头操作符将 Lambda 表达式拆分成两部分:
左侧:Lambda 表达式的参数列表
右侧:Lambda 表达式中所需执行的功能, 即 Lambda 体
语法格式一:无参数,无返回值
() -> System.out.println(“Hello Lambda!”);
语法格式二:有一个参数,无返回值
(x) -> System.out.println(x)
语法格式三:若只有一个参数,小括号可以省略不写(为了方便阅读和理解,常常不会省略小括号,即采用语法格式二那样)
x -> System.out.println(x)
语法格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句(有多条语句就需要大括号,并将多条语句放入其中)
Comparator com = (x, y) -> {
System.out.println(“函数式接口”);
return Integer.compare(x, y);
};
语法格式五:若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写
Comparator com = (x, y) -> Integer.compare(x, y);
语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
(Integer x, Integer y) -> Integer.compare(x, y);
上联:左右遇一括号省
下联:左侧推断类型省
横批:能省则省
最后
笔者已经把面试题和答案整理成了面试专题文档
arator com = (x, y) -> Integer.compare(x, y);
语法格式六:Lambda 表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即“类型推断”
(Integer x, Integer y) -> Integer.compare(x, y);
上联:左右遇一括号省
下联:左侧推断类型省
横批:能省则省
最后
笔者已经把面试题和答案整理成了面试专题文档
[外链图片转存中…(img-LhXLtDBz-1719158910862)]
[外链图片转存中…(img-20FaZ6ya-1719158910863)]
[外链图片转存中…(img-Ku4yQgu8-1719158910863)]
[外链图片转存中…(img-wSkb9xVm-1719158910864)]
[外链图片转存中…(img-yxoPIbQJ-1719158910864)]
[外链图片转存中…(img-l3hTh7is-1719158910865)]