欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Lambda第一讲

程序员文章站 2024-03-16 08:39:28
...

牛刀小试

匿名内部类实现对字符串长度的排序

@Test
	public void test1(){
		Comparator<String> com  = new Comparator<String>() {
			int num =0;
			@Override
			public int compare(String o1, String o2) {
				num++;
				System.out.println("比较第:"+num+" 次");
				return Integer.compare(o1.length(),o2.length());//由小到大,若想降序 前边加‘-’负号
			}
		};
		//TreeSet传入比较器
		TreeSet<String> ts = new TreeSet<>(com);
        ts.add("aaa");
        ts.add("a");
        ts.add("aaaaaaaaaa");
		ts.add("aa");
		System.out.println(ts);
		/**
		 * TreeSet比较是以二叉树的方式比较的
		 * 第一次以“aaa”为根节点存入“aaa”
		 * 第二次比较o1为“a”,o2为“aaa” 比较长度 o1比o2小所以放左边
		 * 第三次比较o1为“aaaaaaaaaa”,o2为“aaa” 比较长度 o1比o2大所以放右边
		 * 第四次比较o1为“aa”,o2为“aaa” 比较长度 o1比o2小,
		 * 		然后o1为“aa”,o2为“a” 比较长度 o1比o2大,所以放在“a”的右边
		 */

运行结果

比较第:1 次
比较第:2 次
比较第:3 次
比较第:4 次
比较第:5 次
[a, aa, aaa, aaaaaaaaaa]

Process finished with exit code 0

简洁写法

//更简洁的写法
TreeSet<String> ts2 = new TreeSet<>(new Comparator<String>(){
	@Override
	public int compare(String o1, String o2) {
		return Integer.compare(o1.length(), o2.length());
	}
	
});

使用Lambda表达式实现对字符串长度的排序

代码:

//现在的 Lambda 表达式
@Test
public void test2(){
	Comparator<String> com = (x,y) -> Integer.compare(x.length(),y.length());
	//若想倒序排列 加个“-” Integer.compare(x.length(),y.length());
	TreeSet<String> ts = new TreeSet<>(com);
	ts.add("aaa");
	ts.add("a");
	ts.add("aaaaaaaaaa");
	System.out.println(ts);

}

运行结果:

[a, aaa, aaaaaaaaaa]

Process finished with exit code 0

员工信息实例

员工信息 :

	List<Employee> 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)
	);

需求:获取公司中年龄小于 35 的员工信息

方式一

方法:

public List<Employee> filterEmployeeAge(List<Employee> emps){
	List<Employee> list = new ArrayList<>();
	
	for (Employee emp : emps) {
		if(emp.getAge() <= 35){
			list.add(emp);
		}
	}
	
	return list;
}

主函数 :

@Test
public void test3(){
	List<Employee> list = filterEmployeeAge(emps);
	
	for (Employee employee : list) {
		System.out.println(employee);
	}
}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=103, name=王五, age=28, salary=3333.33]
Employee [id=104, name=赵六, age=8, salary=7777.77]

Process finished with exit code 0

方式二

策略设计模式

  1. 新建一个接口:
package testLambda.java8;

@FunctionalInterface
public interface MyPredicate<T> {

	public boolean test(T t);
	
}
  1. 写一个该接口的实现类
package testLambda.java8;

public class FilterEmployeeForAge implements MyPredicate<Employee>{

	@Override
	public boolean test(Employee t) {
		return t.getAge() <= 35;
	}

}
  1. 使用策略模式写一个filterEmployee方法
	//优化方式一:策略设计模式
	public List<Employee> filterEmployee(List<Employee> emps, MyPredicate<Employee> mp){
		List<Employee> list = new ArrayList<>();
		
		for (Employee employee : emps) {
			if(mp.test(employee)){
				list.add(employee);
			}
		}
		
		return list;
	}
  1. 主函数测试
	@Test
	public void test4(){
		List<Employee> list = filterEmployee(emps, new FilterEmployeeForAge());
		for (Employee employee : list) {
			System.out.println(employee);
		}
	}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=103, name=王五, age=28, salary=3333.33]
Employee [id=104, name=赵六, age=8, salary=7777.77]

同样的如果需求更改
需求:获取公司中工资大于 5000 的员工信息

我们还得新建个类:

package testLambda.java8;

public class FilterEmployeeForSalary implements MyPredicate<Employee> {

	@Override
	public boolean test(Employee t) {
		return t.getSalary() >= 5000;
	}

}

然后在主函数继续调用:

	List<Employee> list2 = filterEmployee(emps, new FilterEmployeeForSalary());
	for (Employee employee : list2) {
		System.out.println(employee);
	}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=102, name=李四, age=59, salary=6666.66]
Employee [id=104, name=赵六, age=8, salary=7777.77]
Employee [id=105, name=田七, age=38, salary=5555.55]

方式三

对于以上的方式,每次更换过滤规则都会重新写一个类来实现接口
所以,我们可以使用匿名内部类来实现该功能
代码:

@Test
public void test5(){
	List<Employee> list  = filterEmployee(emps, new MyPredicate<Employee>() {
		@Override
		public boolean test(Employee employee) {
			return employee.getSalary() >=  5000;
		}
	});
	for (Employee employee : list) {
		System.out.println(employee);
	}
}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=102, name=李四, age=59, salary=6666.66]
Employee [id=104, name=赵六, age=8, salary=7777.77]
Employee [id=105, name=田七, age=38, salary=5555.55]

Process finished with exit code 0

方式四

当然最好的方式是用用Lambda表达式了

//优化方式三:Lambda 表达式
@Test
public void test6(){
	List<Employee> list2 = filterEmployee(emps,(t) -> t.getSalary() >= 5000);
	list2.forEach(System.out::println);
}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=102, name=李四, age=59, salary=6666.66]
Employee [id=104, name=赵六, age=8, salary=7777.77]
Employee [id=105, name=田七, age=38, salary=5555.55]

方式五

使用StremAPI

//优化方式四:Stream API
@Test
public void test7(){
	emps.stream()
		.filter((e) -> e.getAge() <= 35)
		.forEach(System.out::println);
	
	System.out.println("----------------------------------------------");
	
	emps.stream()
		.map(Employee::getName)
		.limit(3)
		.sorted()
		.forEach(System.out::println);
	System.out.println("----------------------------------------------");
	emps.stream()
			.map(Employee::getAge)
			.filter((e) -> e<=35)
			.forEach(System.out::println);

}

运行结果:

Employee [id=101, name=张三, age=18, salary=9999.99]
Employee [id=103, name=王五, age=28, salary=3333.33]
Employee [id=104, name=赵六, age=8, salary=7777.77]
----------------------------------------------
张三
李四
王五
----------------------------------------------
18
28
8