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