java 8

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

原始做法:

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

策略模式优化:

public class Employee {

    private int id;
    private String name;
    private int age;
    private double salary;

}

    List emps = Arrays.asList(
            new Employee(101, "一一一", 18,11111.11),
            new Employee(102, "二二二", 28,2222.22),
            new Employee(103, "三三三", 38, 3333.33),
            new Employee(104, "四四四", 48, 44444.44),
            new Employee(105, "五五五", 58, 55555.55)
    );

1:提出一个抽象接口 让实现它的对象指定实现方式比如:按年龄或这收入排序

@FunctionalInterface 表明是一个函数是接口 函数接口只能有一个抽象方法

@FunctionalInterface
public interface MyPredicate {

    public boolean test(T t);
    
}

 2根据具体要求实现

实现按照年需求

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;
    }

}

调用只有这个一个只有参数不同:

    public List filterEmployee(List emps, MyPredicate mp){
        List list = new ArrayList<>();
        
        for (Employee employee : emps) {
            if(mp.test(employee)){
                list.add(employee);
            }
        }
        
        return list;
    } 

Java8优化:

lambda:表示上面调用方法:

List list = filterEmployee(emps, (e) -> e.getAge() <= 35);

List list2 = filterEmployee(emps, (e) -> e.getSalary() >= 5000); 

Java8Stream优化:

emps.stream()
            .filter((e) -> e.getAge() <= 35)
            .forEach(System.out::println); 

不需要定义接口和实现直接用Stream API 

 一:lambda 表达式

/*
 * 一、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);
 * 
 * 二、Lambda 表达式需要“函数式接口”的支持
 * 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。 可以使用注解 @FunctionalInterface 修饰
 *              可以检查是否是函数式接口
 */

需求  实现对上面集合的按照不同需求排序

    public void test(){
        Collections.sort(emps, (e1, e2) -> {
            if(e1.getAge() == e2.getAge()){
                    return e1.getName().compareTo(e2.getName());
            }else{
                return -Integer.compare(e1.getAge(), e2.getAge());
            }
        });
        
        for (Employee emp : emps) {
            System.out.println(emp);
        }
    }

需求 设计一个带泛型的函数接口 R为返回值 对两个T做指定操作

@FunctionalInterface
public interface Myinterface {
    R valuer(T t1,T t2);
}

传两个整数求和

public static void main(String[] args) {
    TestOne o=new TestOne();
    o.test3();
}

public void test2(int x,int y,Myinterface my){
    System.out.println(my.valuer(x,y));

}
public void test3(){
    test2(2,5,(x,y)->x+y);
}

自己设计接口麻烦 java 8 帮我设计大部分场景的接口 即 下面的函数接口

 /*
 * Java8 内置的四大核心函数式接口
 * 
 * Consumer : 消费型接口
 *         void accept(T t);
 * 
 * Supplier : 供给型接口
 *         T get(); 
 * 
 * Function : 函数型接口
 *         R apply(T t);
 * 
 * Predicate : 断言型接口
 *         boolean test(T t);
 * 
 */

Consumer : 消费型接口说明:无返回值型:

举例:传一个参数,指定参数做什么事情,比如判断,计算等:

写一个方法指定Consumer消费的参数和Consumer

public void happy(double money, Consumer con){
        con.accept(money);
    }

public void test1(){
        happy(10000, (m) -> System.out.println(m+250));
    } 

 Supplier 供给型接口 无参数型:

public List test4(List list,Supplier> su){
    Collections.sort(list);
    return list=su.get();
}
public  void test5(){
    List integers = test4(list, () ->list);
}

根据你指定的规则给你生产一个你需要的结果 

Function 函数型接口:

public void test3(){
		String newStr = strHandler("    你好Java    ", (str) -> str.trim());
		System.out.println(newStr);
		
		String subStr = strHandler("我爱的我的祖国", (str) -> str.substring(2, 5));
		System.out.println(subStr);
	}
	
	//需求:用于处理字符串
	public String strHandler(String str, Function fun){
		return fun.apply(str);
	}

Predicate 断言型接口:

public void test4(){
		List list = Arrays.asList("Hello", "Java", "Lambda", "www", "ok");
		List strList = filterStr(list, (s) -> s.length() > 3);
		
		for (String str : strList) {
			System.out.println(str);
		}
	}
	
	//需求:将满足条件的字符串,放入集合中
	public List filterStr(List list, Predicate pre){
		List strList = new ArrayList<>();
		
		for (String str : list) {
			if(pre.test(str)){
				strList.add(str);
			}
		}
		
		return strList;
	}

方法引用:

    若 Lambda 体中的功能,已经有方法提供了实现,可以使用方法引用(可以将方法引用理解为 Lambda 表达式的另外一种表现形式)

用法

 1. 对象的引用 :: 实例方法名
 2. 类名 :: 静态方法名
 3. 类名 :: 实例方法名

注意:
 ①方法引用所引用的方法的参数列表与返回值类型,需要与函数式接口中抽象方法的参数列表和返回值类型保持一致!
②若Lambda 的参数列表的第一个参数,是实例方法的调用者,第二个参数(或无参)是实例方法的参数时,格式: ClassName::MethodName
构造器引用 :构造器的参数列表,需要与函数式接口中参数列表保持一致

数组引用
   类型[] :: new;

举例:

	//对象的引用 :: 实例方法名
	@Test
	public void test2(){
		Employee emp = new Employee(101, "张三", 18, 9999.99);
		
		Supplier sup = () -> emp.getName();
		System.out.println(sup.get());
		
		System.out.println("----------------------------------");
		
		Supplier sup2 = emp::getName;
		System.out.println(sup2.get());
	}
//类名 :: 静态方法名
@Test
	public void test4(){
		Comparator com = (x, y) -> Integer.compare(x, y);
		
		System.out.println("-------------------------------------");
		
		Comparator com2 = Integer::compare;
	}
	
	@Test
	public void test3(){
		BiFunction fun = (x, y) -> Math.max(x, y);
		System.out.println(fun.apply(1.5, 22.2));
		
		System.out.println("--------------------------------------------------");
		
		BiFunction fun2 = Math::max;
		System.out.println(fun2.apply(1.2, 1.5));
	}
//类名 :: 实例方法名
	@Test
	public void test5(){
		BiPredicate bp = (x, y) -> x.equals(y);
		System.out.println(bp.test("abcde", "abcde"));
		
		System.out.println("-----------------------------------------");
		
		BiPredicate bp2 = String::equals;
		System.out.println(bp2.test("abc", "abc"));
		
		System.out.println("-----------------------------------------");
		
		
		Function fun = (e) -> e.show();
		System.out.println(fun.apply(new Employee()));
		
		System.out.println("-----------------------------------------");
		
		Function fun2 = Employee::show;
		System.out.println(fun2.apply(new Employee()));
		
	}
//构造器引用
	@Test
	public void test7(){
		Function fun = Employee::new;
		
		BiFunction fun2 = Employee::new;
	}
	
	@Test
	public void test6(){
		Supplier sup = () -> new Employee();
		System.out.println(sup.get());
		
		System.out.println("------------------------------------");
		
		Supplier sup2 = Employee::new;
		System.out.println(sup2.get());
	}
//数组引用
	@Test
	public void test8(){
		Function fun = (args) -> new String[args];
		String[] strs = fun.apply(10);
		System.out.println(strs.length);
		
		System.out.println("--------------------------");
		
		Function fun2 = Employee[] :: new;
		Employee[] emps = fun2.apply(20);
		System.out.println(emps.length);
	}
	

你可能感兴趣的:(mycat,中间件,java)