一、Lambda表达式
Lambda表达式: lambda表达式被称为闭包。函数式编程,就是为了简化代码,让代码更加简洁。
下边举个例子。下面两个线程都可以打印相应的内容,其中runnable1是内部类写法,runnable是对应的Lambda表达式写法。
public class Demo {
public static void main(String[] args) {
//当接口下面只有一个抽象方法的时候 可以简写
Runnable runnable1 = new Runnable() {
@Override
public void run() {
System.out.println("我是内部类输出");
}
};
Runnable runnable2 = ()-> System.out.println("我是Lambda表达式输出");
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
二、Lambda表达式的语法格式
函数式接口,接口下面有且只有有一个抽象类,才能使用Lambada
接口 接口对象 = ()->表达式; 无参无返回值的
接口 接口对象 = (parameter)->表达式; 有参无返回值的
接口 接口对象 = ()->{表达式;} 无参有返回值的
接口 接口对象 = (parameter)->{表达式;} 有参有返回值的
2.1、无参无返回值的
interface Computer {
void coding();
}
public class Demo {
public static void main(String[] args) {
//接口 接口对象 = ()->表达式;
//第一种的展开写法
Computer computer = ()-> System.out.println("敲代码");
test(computer);
//第一种
test(()-> System.out.println("嗷嗷叫的敲代码"));
//第二种
test(()-> System.out.println("打游戏"));
//第二种的展开写法
test(new Computer() {
@Override
public void coding() {
System.out.println("嗷嗷叫的打游戏");
}
});
}
public static void test (Computer computer) {
computer.coding();
}
}
2.2、有参无返回值
interface A {
void eat (String name, int age);
}
public class Demo {
public static void main(String[] args) {
//展开写法
test(new A() {
@Override
public void eat(String name, int age) {
System.out.println(name+ "年龄为:" + age + ",在吃黄焖鸡");
}
}, "张三", 12);
//把方法中的接口变成了lambada表达式
//接口 接口对象 = (parameter)->表达式;
//Lambda表达式写法
test((name, age)-> System.out.println(name+ "年龄为:" + age + ",在吃大盘鸡"), "李四", 24);
}
public static void test (A a, String name, int age) {
a.eat(name, age);
}
}
2.3、无参有返回值
interface B {
int num();
}
public class Demo {
public static void main(String[] args) {
//展开写法
test(new B() {
@Override
public int num() {
return 50;
}
});
//lambda表达式写法
test(()->{return 50;});
}
public static void test (B b) {
System.out.println(b.num());
}
}
2.4、有参有返回值
interface C {
int add(int a, int b);
}
public class Demo1 {
public static void main(String[] args) {
test((a, b) -> a + b, 4, 5);
}
public static void test(C c, int a, int b) {
int sum = c.add(a, b);
System.out.println(sum);
}
}
三、Stream流
基于Lambda之后,jdk8又引入一个关于集合类库目前的弊端的解决方案。叫stream流。
//通过list集合获取流对象,也可以用set集合
ArrayList<String> strings = new ArrayList<>();
strings.add("张三");
strings.add("李四");
strings.add("王五");
System.out.println(strings);
//可以list集合变成一个流对象
Stream<String> stream = strings.stream();
System.out.println(stream);//内存地址
//也可以用map集合获取流对象
Set<Map.Entry<String, String>> entries = maps.entrySet();
Stream<Map.Entry<String, String>> stream = entries.stream();
四、Stream流对象下面的方法
方法的名字 | 方法的作用 | 方法种类 | 是否支持链式操作 |
---|---|---|---|
count | 统计个数 | 终结方法 | 否 |
forEach | 遍历数据的 | 终结方法 | 否 |
filter | 过滤数据 | 可以拼接 | 是 |
limit | 取前几个数据 | 可以拼接 | 是 |
skip | 跳过前几个 | 可以拼接 | 是 |
map | 映射方法 | 可以拼接 | 是 |
concat | 拼接 | 可以拼接 | 是 |
非终结方法可以调用其他方法
count :统计流中的个数,返回值是long类型的数据(写在最后)
forEach: 遍历流中数据的(写在最后)
//filter方法:
Stream<T> filter(Predicate<? super T> predicate)
//strings.stream().filter(new Predicate<String>() {
// @Override
// public boolean test(String s) {
// //s流中字符串每个的数据
// boolean b = s.endsWith("坤");
// return b;
// }
limit :限制输出个数
skip :跳过前边的几个值
concat :合并两个流
//Stream.concat(stream, stream1)
map :处理映射关系
//map((s)->Integer.parseInt(s))
//strings.stream().map(new Function<String, Integer>() {
// @Override
// public Integer apply(String s) {
// int i = Integer.parseInt(s);
// return i;
// }
//)
五、收集流
真实的开发的时候,最终的结果还是集合 流只是扮演了中间处理数据的角色。
stream.collect(Collectors.toList()) toList(); 将流转为List集合
stream.collect(Collectors.toSet()) toSet(); 将流转为Set集合