一、Lambda
Lambda表达式的定义需要有函数式接口(只有一个抽象方法需要实现的接口称为函数式接口),可以简洁代码,但不直观。函数式接口中抽象方法有参数和返回值对书写Lambda基本没有变化。@FunctionalInterface注解标注的即是函数式接口,以示区别(如Runnable、Comparator
)。
- 参数列表的省略规则
若参数列表有参数,参数类型可省,一省全省。 若参数列表只有一个参数,类型和小括号都可省,若括号省略,类型必省。
- 方法体的省略规则
若方法体中只存在一条语句,则方法体大括号、当前语句分号、return 都可省,一省全省。
创建线程示例,无返回值:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"启动");
}
}).start();
new Thread(()-> System.out.println(Thread.currentThread().getName()+"启动")).start();
集合排序示例,有返回值:
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
//匿名内部类
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
System.out.println("list正序排列 = " + list);
//lambda简化
Collections.sort(list, (o1, o2) -> o2 - o1);
System.out.println("list倒序排列 = " + list);
针对无参、多参、有无返回值的测例
public class TestClass10Two {
public static void main(String[] args) {
//无参
Test1 test1 = () -> {
System.out.println("test1");
};
test1.test();
//有两个参 有返回值
Test2 test2 = (name, age) -> {
System.out.println("test2 = " + name + age + "岁了");
return age + 1;
};
System.out.println("test2 中 返回值 = " + test2.test("迪迦", 18));
//仅有一个参 有返回值
Test3 test3 = name -> {
System.out.println("test3 = name = " + name);
return name + "666";
};
System.out.println("test3 中 返回值 = " + test3.test("迪迦"));
//当⼀个方法体中的逻辑,有且只有⼀句的情况下,⼤括号可以省略
Test4 test4 = name -> System.out.println("name = " + name);
test4.test("迪迦没能量了");
//方法中仅有⼀个返回语句,此时省略掉大括号的同时,必须省略return
Test3 test33 = name -> name + "666";
System.out.println("test33 中 返回值 = " + test33.test("怪兽"));
//对静态方法的引用
Test5 test5 = Ultraman::ultraman;
System.out.println("静态方法返回值 = " + test5.test("迪迦", "怪兽"));
Test5 test55 = new Ultraman()::ultraman2;
System.out.println("非静态方法返回值 = " + test55.test("怪兽", "狗"));
}
}
//有且只有一个实现类必须要实现的抽象方法,所以是函数式接口
interface Test1 {
public void test();
}
//有两个参 有返回值
interface Test2 {
public int test(String name, int age);
}
//仅有一个参 有返回值
interface Test3 {
public String test(String name);
}
//仅有一个参 无返回值
interface Test4 {
public void test(String name);
}
interface Test5 {
String test(String a, String b);
}
class Ultraman {
public static String ultraman(String a, String b) {
//省略的逻辑
return a + "打" + b;
}
public String ultraman2(String a, String b) {
//省略的逻辑
return a + "打" + b;
}
}
结果:
test1
test2 = 迪迦18岁了
test2 中 返回值 = 19
test3 = name = 迪迦
test3 中 返回值 = 迪迦666
name = 迪迦没能量了
test33 中 返回值 = 怪兽666
静态方法返回值 = 迪迦打怪兽
非静态方法返回值 = 怪兽打狗
二、Sream流
Stream流是极大的简化了对于集合、数组等的操作,只要是可以转换成流的都可以简化(有时看起来并不简化)。一个流式处理可以分为三个部分:转换成流、中间操作、终端操作。
特点:阅后即焚、一次性使用
//所有Collection的实现类都具stream方法,能够直接使用集合对象调用该方法。
Stream s = 集合.stream();
//Stream接口本身存在一个静态方法:of,可以指定该类型的数组或者单个的多个数据也可以转换为流
Stream<String> s1 = Stream.of(arr);
Stream<String> s2 = Stream.of("A", "B", "C");
//获取键值对对象对应的流
Stream<Map.Entry<String, String>> s1 = map.entrySet().stream();
//获取键对应的流
Stream<String> s2 = map.keySet().stream();
//获取值对应的流
Stream<String> s3 = map.values().stream();
1.终端方法
作用 |
|
long count(); |
统计流中数据的个数 |
void forEach(Consumer<? super T> action); |
遍历流中的数据 |
collect(Collectors.toList()); |
将流中数据收集到List集合中 |
collect(Collectors.toSet ()); |
将流中数据收集到Set集合中 |
Object[] toArray(); |
将流中数据收集到数组中 |
2.中间操作方法
作用 |
|
Stream<T> filter (Predicate<? super T> predicate); |
根据条件过滤不需要的数据 |
Stream<T> limit (long n); |
|
Stream<T> skip (long n); |
跳过流中前n个数据,不足n个则没有数据 |
Stream<T> distinct (); |
去重(equals比较为true的元素会被去重) |
Stream<T> sorted (); Stream<T> sorted |
将流中元素按照自然排序的规则排序 将流中元素按照自定义比较器规则排序 |
<R> Stream<R> map(Function<? super T, ? extends R> mapper); | 将流中数据转换为另外一种想要的数据 |
public static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b) | 将两个流合并为一个流 |
测例:
public class TestClass10Three {
public static void main(String[] args) {
//Stream自带的of静态方法,指类型的数组或者单个的多个数据转换为流
//Stream流只能使用一次,阅后即焚,所以选择每次生成新的流
// Stream<Ultraman2> um = Stream.of(new Ultraman2("purple", "空中型")...);
List<Ultraman2> um = Arrays.asList(new Ultraman2("black", "黑暗型"),
new Ultraman2("purple", "空中型"),
new Ultraman2("red", "力量型"),
new Ultraman2("black", "黑暗型"));
//流的终端操作:记数、遍历输出、放入(list、set、map)、放入数组
//记数
System.out.println(um.stream().count());
//遍历输出
// um.stream().forEach(System.out::println);
//放入(list、set)
List<Ultraman2> list = um.stream().collect(Collectors.toList());
Object[] objects = um.stream().toArray();//放入数组
//流的中间操作方法:过滤,获取前n数据、跳过前n数据、去重、排序、拼接、map映射(将流中数据转换为另外一种想要的数据)
//过滤
um.stream().filter(u -> !"黑暗型".equals(u.getType())).forEach(s -> System.out.println("过滤后的元素" + s));
//获取流中前n个数据,不足n个获取全部
um.stream().limit(2).forEach(s -> System.out.println("获取前n个元素" + s));
//跳过流中前n个数据,不足n个则没有数据
um.stream().skip(2).forEach(s -> System.out.println("跳过前n个元素" + s));
//去重(equals比较为true的元素会被去重)
um.stream().distinct().forEach(s -> System.out.println("去重后的元素" + s));
//将流中元素按照自然排序的规则排序
Arrays.asList("1", "3", "8", "4", "2").stream().sorted().forEach(System.out::println);
um.stream().sorted((s1, s2) -> (s1.getColor().compareto(s2.getColor()))).forEach(s -> System.out.println("按照颜色ASCII排序" + s));//将流中元素按照自定义比较器规则排序
//将流中元素按照自定义比较器规则排序
Stream.concat(Arrays.asList("迪", "迦").stream(), Arrays.asList("怪", "兽").stream()).forEach(s -> System.out.println("拼接后的元素" + s));
//拿到部分符合要求的值
um.stream().map(s -> s.getColor()).distinct().forEach(s -> System.out.println("拿到的新值" + s));
}
}
class Ultraman2 {
private String color;
private String type;
//构造方法
//toString
//equals
//getter、setter
}