Lambda表达式
1.Lambda表达式是特殊的匿名内部类,语法更简洁
2.Lambda表达式允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递
语法
()->{}
使用lambda表示的注意事项
- 1、形参的类型可以推断,所以可以省略
- 2、如果方法的参数只有一个,()可以省略
- 3、如果参数列表为空,必须要写上()、
- 4、如果方法体中只有一行代码,大括号、分号、可以省,如果有返回return也可以省 。但是要一起省
- 5、lambda表达式不会生成class文件
示例
public class Demo1 {
public static void m1(String name,MyInterface myInterface){
myInterface.show(name);
}
//匿名内部类
public static void main(String[] args) {
m1("张三", new MyInterface() {
@Override
public void show(String name) {
System.out.println(name);
}
});
//lambda表达式
m1("李四",name -> System.out.println(name));
}
}
函数式接口
如果一个接口只有一个抽象方法,则该接口称之为函数式接口。
函数式接口可以使用Lambda表达式,Lambda表达式会被匹配到这个抽象方法上 。
- @FunctionalInterface 注解检测接口是否符合函数式接口规范。
常见函数式接口
方法引用
方法引用是Lambda表达式的一种简写形式。
如果Lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用。
常见形式:
- 对象::实例方法
public class Demo4 {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.forEach(new Consumer<Integer>() {
@Override
public void accept(Integer integer) {
System.out.println(integer);
}
});
list.forEach(i-> System.out.println(i));
//集合遍历
list.forEach(System.out::println);
}
}
- 类::静态方法
public class Demo6 {
public static void m1(Supplier<Double> supplier){
System.out.println(supplier.get());
}
public static void main(String[] args) {
m1(new Supplier<Double>() {
@Override
public Double get() {
return Math.random();
}
});
m1(()->Math.random());
//方法引用
m1(Math::random);
}
}
- 类::实例方法
public class Demo5 {
public static void m1(String s, Function<String,String>function){
System.out.println(function.apply(s));
}
public static void main(String[] args) {
m1("abc", new Function<String, String>() {
@Override
public String apply(String s) {
return s.toUpperCase();
}
});
m1("abc",s->s.toUpperCase());
//方法引用
m1("abc",String::toUpperCase);
}
}
- 类::new
public class Demo7 {
public static void m1(String s, Function<String,Person> function){
System.out.println(function.apply(s));
}
public static void main(String[] args) {
m1("zs", new Function<String, Person>() {
@Override
public Person apply(String s) {
return new Person(s);
}
});
m1("zs",s -> new Person(s));
m1("zs",Person::new);
}
}
class Person{
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
Stream流
流(Stream)与集合类似,但集合中保存的是数据,而Stream中保存对集合或数组数据的操作。
特点
- Stream 自己不会存储元素。
- Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
- Stream 操作是延迟执行的,会等到需要结果的时候才执行。
使用步骤
创建: - 新建一个流。
中间操作: - 在一个或多个步骤中,将初始Stream转化到另一个Stream的中间操作。
终止操作: - 使用一个终止操作来产生一个结果。该操作会强制之前的延迟操作立即执行,在此之后,该Stream就不能使用了。
创建Stream流
public class Demo8 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(10);
list.add(100);
//创建stream流的三种方式
//方式1(最常用)
Stream<Integer> stream = list.stream();
stream.forEach(System.out::println);
int[] arr={1,2,3,4};
//方式2
IntStream stream1 = Arrays.stream(arr);
stream1.forEach(System.out::println);
//方式3
Stream<Integer> integerStream = Stream.of(1, 2, 3);
integerStream.forEach(System.out::println);
}
}
常见中间操作:
- filter、limit、skip、distinct、sorted
- map
- parallel
示例:
public class Demo9 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("1000");
list.add("1");
list.add("11111");
list.add("11");
list.add("123");
//过滤filter
list.stream().filter(s -> s.length()>3).forEach(System.out::println);
System.out.println("--------------------");
//去重distinct
list.stream().distinct().forEach(System.out::println);
System.out.println("--------------------");
//对数据进行操作map
list.stream().map(s->Integer.valueOf(s)).forEach(System.out::println);
System.out.println("--------------------");
//排序
list.stream().map(s->Integer.valueOf(s)).sorted().forEach(System.out::println);
List<People> peopleList = Arrays.asList(new People("zs", 10000), new People("ls", 100000),
new People("ww", 20000));
peopleList.stream().sorted((o1, o2) -> o2.getSalary()-o1.getSalary()).forEach(System.out::println);
//limit 前几条
list.stream().limit(2).forEach(System.out::println);
System.out.println("-------------------------------");
//skip 跳过
list.stream().skip(3).limit(2).forEach(System.out::println);
System.out.println("-------------------------------");
//parallel 多线程执行
list.stream().parallel().forEach(s -> System.out.println(Thread.currentThread().getName()+"-------"+s));
}
}
class People{
String name;
Integer salary;
public People(String name, Integer salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getSalary() {
return salary;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", salary=" + salary +
'}';
}
}
常见终止操作:
- forEach、min、max、count
- reduce、collect(将Stream流对象转换成List、set、Map集合)
public class Demo10 {
public static void main(String[] args) {
List<String> list = Arrays.asList("1", "9", "10", "1", "8");
//最小值
Optional<Integer> min = list.stream().map(Integer::valueOf).min((o1, o2) -> o1 - o2);
System.out.println(min.get());
//最大值
Optional<Integer> max = list.stream().map(Integer::valueOf).max((o1, o2) -> o1 - o2);
System.out.println(max.get());
//统计个数
long count = list.stream().count();
System.out.println(count);
//reduce
Optional<Integer> reduce1 = list.stream().map(Integer::valueOf).reduce((o1, o2) -> o1 + o2);
//reduce(0, Integer::sum) 0是累加的和
Integer reduce = list.stream().map(Integer::valueOf).reduce(0, Integer::sum);
System.out.println(reduce);
System.out.println(reduce1.get());
//去重,并转成一个新集合distinct,collect(Collectors.toList())
List<Integer> list1 = list.stream().map(Integer::valueOf).distinct().collect(Collectors.toList());
System.out.println(list1);
}
}
新时间API
public class Demo11 {
public static void main(String[] args) {
LocalDate d1 = LocalDate.now();
System.out.println(d1);
LocalTime d2 = LocalTime.now();
System.out.println(d2);
LocalDateTime d3 = LocalDateTime.now();
System.out.println(d3);
LocalDateTime d4 = LocalDateTime.of(2023, 1, 1, 12, 0, 0);
System.out.println(d4);
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:dd:ss");
String date = dateTimeFormatter.format(LocalDateTime.now());
System.out.println(date);
}
}
接口新特性
在JDK8环境中,接口中的方法不再是只能有抽象方法,还可以有静态方法和default方法。实现类只需要实现
它的抽象方法即可。其目的是为了解决扩展接口方法时,对实现类造成影响