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