Java 学习 lambda表达式 闭包 匿名函数

//lambda表达式
//也叫闭包,也叫匿名函数(方法)。
//Java8才出的新特性。
// -> 是lambda标识。
// ->左侧是参数列表,如果参数只有1个,可以省略小括号。0参数的时候,小括号必须有
// ->右侧是方法体。如果方法体只有1行,可以省略大括号以及return
//
//lambda表达式依赖于 函数式接口而存在。
// 函数式接口是一种特殊的接口,这个接口只有一个抽象方法。
//
//lambda表达式是匿名类的简化版本,因为接口只有一个抽象方法,因此可以去掉创建
// 匿名类对象的过程
//以前: MyInterface m = new MyInterface(){
// public void test(){System.out.println(“hello”);}
// }
//现在:()->{System.out.println(“hello”);}
//除了可以省略匿名类对象的创建过程,如果方法体只有1行代码,还可以省略{}以及return
//最终:()->System.out.println(“hello”);
//实际上,labmda是强化了编译器。在你把java文件编译成class文件的时候,
//会还原回以前的匿名类格式。
/*

  • 既然lambda表达式是依赖函数式接口存在的,

  • 是不是说想用lambda就得先建一个接口呢?

  • 系统提供很多与lambda配套的函数式接口

  • 他们在java.util.function包里

  • */

     public class TestLambda {
    
     public static void main(String[] args) {
     
     	//		MyInterface mi = new MyInterface() {
     //			@Override
     //			public void test() {
     //				System.out.println("哈哈");
     //			}
     //		};
     
     MyInterface mi = ()->System.out.println("哈哈");
     mi.test();
     
     MyInterface mi2 = ()->{
     	System.out.println("haha");
     	System.out.println("hahahaha");
     	if(3>2) {
     		System.out.println(3*2);
     	}
     };
     mi2.test();
     
     
     
     MyInterface2 mi10 = (String str,int n)->System.out.println(str+n);
     mi10.method("hello", 100);	
     
     MyInterface2 mi11 = (x,y)->{
     	System.out.println(x.toUpperCase());
     	System.out.println(y*y);
     };
     mi11.method("abcd", 10);
     }
     }
     ********
    

基本用法:

public class Testlambda {

public static void main(String[] args) {
	//计算数的值,和、差、积、商等
	MyInterface<Integer,Integer,Integer> m1 = (x,y)->x+y;
	int a = m1.op(100, 200);
	System.out.println(a);

	MyInterface<Integer,Integer,Double> m2 = (x,y)->x*1.0/y;
	System.out.println(m2.op(20, 50));
	
	MyInterface<Integer,Integer,Long> m3 = (x,y)->(long)Math.pow(x, y);
	System.out.println(m3.op(2, 3));
	
	//计算2个整数的最大值
	MyInterface<Integer, Integer, Integer> m4 = (x,y)->x>y?x:y;
	System.out.println(m4.op(10, 30));
	//计算从第一个数到第二个数的累加和。
	MyInterface<Integer, Integer, Integer> m5 = (x,y)->{
			int m = x > y ? x : y;
			int n = x < y ? x : y;
			int sum = 0;
			for(int i = n; i <= m;i++) {
				sum += i;
			}
			return sum;
	};
	System.out.println(m5.op(12, 5));
	
}
}

定义一个Employee类

public class Employee {

private String name;
private int age;
private double salary;
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public int getAge() {
	return age;
}
public void setAge(int age) {
	this.age = age;
}
public double getSalary() {
	return salary;
}
public void setSalary(double salary) {
	this.salary = salary;
}
public Employee() {
	super();
	// TODO Auto-generated constructor stub
}
public Employee(String name,int age) {
	super();
	this.name = name;
	this.age = age;
}

public Employee(String name, int age, double salary) {
	super();
	this.name = name;
	this.age = age;
	this.salary = salary;
}
@Override
public String toString() {
	return "Employee [name=" + name + ", age=" + age + ", salary=" + salary + "]";
}
}

lambda 4大内置函数式接口

public class Test {

public static void main(String[] args) {
	//Consumer  有参数 无返回值  void accept(T t)
	//它是父接口,它有很多子接口
	
	Consumer<String> c1 = (str)->System.out.println(str);
	c1.accept("    hello world");
	Consumer<String> c2 = (str)->System.out.println(str.trim());
	c2.accept("    \thello world   ");
	
	
	BiConsumer<Integer,Double> b1 = (a,b)->System.out.println(a * b);
	b1.accept(10, 3.14);
	
	//Supplier  无参数 有返回值
	Supplier<Integer> s = ()->{
		Random r = new Random();
		int x = r.nextInt(100);
		return x;
	};
	
	System.out.println(s.get());
	
	Employee e = new Employee("zhangsan",25,10000);
	Supplier<String> s2 = ()->e.getName();
	System.out.println(s2.get());
	
	//Function 有参数 有返回值
	Function<String,String> f = (str)->str.toLowerCase();
	String str = f.apply("Hello World");
	System.out.println(str);
	
	Function<Integer,String> f2 = (a) -> "hello"+a;
	System.out.println(f2.apply(1000));
	
	BiFunction<Integer, Integer, Integer> bf = (a,b)->a+b;
	System.out.println(bf.apply(10,20));
	
	//Predicate  有参数,有boolean返回值
	Predicate<Employee> p = (n)->n.getAge()>20;
	System.out.println(p.test(e));	
}
}

/*

  • 方法引用

  • 如果lambda表达式的 实现体(->右侧的)所表述的

  • 功能与一个已知的方法功能一致,就可以使用已知的方法代替lambda的实现体

  • 方法引用可以看成是lambda表达式的另外一种写法。

  • 被引用的方法必须 参数类型和返回值类型与

  • 函数式接口中的方法参数类型以及返回值类型一致。

  • 三种格式:

  • 对象::实例方法

  • 类::静态方法

  • 类::实例方法

  • 构造器(构造方法)引用

  • 类名::new

  • */

     public class TestFunctionYinYong {
    
     public static void main(String[] args) {
     
     PrintStream p = System.out;
     Consumer<String> c = (str)->p.println(str);
     c.accept("hello world");
     
     Consumer<String> c1 = System.out::println;
     c1.accept("我很火,我是四火哥");
     
     Consumer<Integer> c2 = System.out::println;
     c2.accept(100);
     
     Employee e = new Employee("zhangsan", 26, 11000);
     
     Supplier<String> s = ()->e.getName();
     Supplier<String> s2 = e::getName;
     System.out.println(s.get());
     
     String string1 = "hello world";
     Function<String, String[]> f = (str) -> str.split(" ");
     Function<String, String[]> f2 = string1::split;
     String[] strs = f2.apply(" ");
     for (String string : strs) {
     	System.out.println(string);
     }
     
     BiFunction<Integer, Integer, Integer> bf = (x,y)->Integer.compare(x, y);
     BiFunction<Integer, Integer, Integer> bf1 = Integer::compare;
     System.out.println(bf1.apply(10, 20));
     
     BiFunction<String, String, Integer> bf3 = (x,y)->x.compareTo(y);
     BiFunction<String, String, Integer> bf2 = String::compareTo;
     System.out.println(bf2.apply("abc", "abe"));
     
     Supplier<Person> s11 = ()->new Person();
     Person per = s11.get();
     System.out.println(per);
     
     Supplier<Person> s22 = Person::new;
     Person per2 = s22.get();
     System.out.println(per2);
     
     Function<String, Person> f11 = (name)->new Person(name);
     Function<String, Person> f22 = Person::new;
     System.out.println(f22.apply("张三"));
     Function<Integer, Person> f33 = Person::new;
     System.out.println(f33.apply(25));
     
     BiFunction<String, Integer, Person> bf11 = Person::new;
     System.out.println(bf11.apply("田七", 23));
     
     //有一个整型参数,返回值是一个字符串数组。
     //需求根据给定的整数值,创建一个与给定值一样大的字符串数组
     Function<Integer, String[]> f55 = String[]::new;
     String[] ss = f55.apply(10);
     //Function<Integer, String[]> f66 = (n)->new String[n];
     System.out.println(ss.length);
     }
     }
    

/*

  • 想要使用stream,分为3步

  • 1、获取(创建) Stream对象

  • 2、中间操作

  • 3、终止操作 forEach

  • */

     public class TestStream {
    
     public static void main(String[] args) {
     //java8 一共有2个特别受瞩目的特性
     //lambda表达式
     //stream
     //创建Stream的四种方式:
     //	1、集合对象.stream()
     //	2、Arrays.stream(数组名)
     //	3、Stream.of(...)
     //	4、无限流:  Stream.iterate()		Stream.generate()
     
     
     List<Employee> emps = new ArrayList<>();
     emps.add(new Employee("zhangsan",22,9000));
     emps.add(new Employee("李四",23,8000));
     emps.add(new Employee("wangwu",32,19000));
     emps.add(new Employee("maliu",18,12000));
     emps.add(new Employee("tianqi",37,90000));
     
     //第一种:通过集合对象获取 Stream
     Stream<Employee> s1 = emps.stream();
     s1.skip(2).forEach(System.out::println);
     
     //第二种:通过数组对象获取Stream
     String[] strs = {"hello","world","java"};
     Stream<String> s2 = Arrays.stream(strs);
     s2.forEach(System.out::println);
     
     //第三种:通过Stream的静态方法 of创建一个流
     Stream<String> s3 = Stream.of("zhangsan","lisi","wangwu");
     s3.forEach(System.out::println);
     
     //第四种: 无限流
     Stream<Integer> s4 = Stream.iterate(1000, (x)->x+2);
     s4.limit(10).forEach(System.out::println);
     
     Stream<Integer> s5 = Stream.generate(()->(int)(Math.random()*100));
     s5.limit(5).forEach(System.out::println);
     }
     }
    

猜你喜欢

转载自blog.csdn.net/weixin_43791238/article/details/89403571