二十三、Java8.0中新增的特性
<< 上一篇
个人整理非商业用途,欢迎探讨与指正!!
文章目录
23.1Lambda表达式
就是特殊的匿名内部类,简化匿名内部类的写法
允许将一个函数(接口)作为方法的参数,把代码向参数一样传递
能被简化的接口中要求只能有一个方法
语法:箭头语法
() -> {}
java
package com.qf.test;
import java.io.File;
import java.io.FileFilter;
import java.io.FilenameFilter;
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) {
// 使用内部类的写法
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("内部类的形式启动线程");
}
}).start();
// 使用Lambda表达式 无需管理接口是什么,只要保证接口中只有一个方法
new Thread(()/*无参方法*/ -> {
System.out.println("Lambda的形式启动线程");
}/*方法体*/).start();
// 省略 当且仅当只有一条语句时,{}可以省略
// 简化写法
new Thread(() -> System.out.println("Lambda的简化形式启动线程")).start();
System.out.println("----------------------------");
File file = new File("D:/");
// 使用内部类
File[] listFiles = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
// TODO Auto-generated method stub
return pathname.getName().startsWith("0");
}
});
// 使用lambda
listFiles = file.listFiles( (File pathname) -> {return pathname.getName().startsWith("0");});
// 简化 {}只有一条语句时可以省略 返回值是return写不用写
listFiles = file.listFiles( (File pathname) -> pathname.getName().startsWith("0"));
// 再次简化 参数不用写类型
listFiles = file.listFiles( (p) -> p.getName().startsWith("0"));
// 再次简化 当只有一个参数()可以省略
listFiles = file.listFiles( a -> a.getName().startsWith("0"));
System.out.println(Arrays.toString(listFiles));
// 两个参数
System.out.println("----------------------------");
listFiles = file.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return name.startsWith("0");
}
});
// 使用lambda
listFiles = file.listFiles( (File dir,String name)->{return name.startsWith("0");});
listFiles = file.listFiles( (File dir,String name)->name.startsWith("0"));
listFiles = file.listFiles( (a,b) -> b.startsWith("0"));
System.out.println(Arrays.toString(listFiles));
}
}
23.2函数式接口
一个接口中只有一个抽象方法,那么该接口可以被称为函数式接口
函数式接口就可以直接使用Lambda表达式
23.2.1自定义函数式接口
java
@FunctionalInterface
public interface MyInter {
void show();
// void eat();不能写
// 因为Object的所有子类都重写了该方法
boolean equals(Object obj);
// JDK1.8之后新增了一些内容
// defalut修饰的方法
default void test01() {
}
// static修饰的方法
static void test02() {
}
}
public class Demo03 {
public static void m1(String name,MyInter mi) {
mi.show(name);
}
public static void main(String[] args) {
m1("张三",new MyInter() {
@Override
public void show(String name) {
System.out.println(name);
}
});
m1("张三",n -> System.out.println(n));
// 消费型接口的再次简化
m1("张三",System.out::println);
}
}
23.2.2常见的函数式接口
接口 | 参数类型 | 返回值 | 描述 |
---|---|---|---|
Consumer 消费型接口 | T | void | 对T进行操作 |
Supplier 供给型接口 | 无 | T | 返回类型T的对象 |
Function<T,R> 函数型接口 | T | R | 对T进行操作,返回R类型 |
Predicate 断言型接口 | T | boolean | 判断T是否满足条件 |
java
// 消费型接口
public class Demo04 {
// 传入一个String,输出它的长度
public static void m1(String str,Consumer<String> consumer) {
consumer.accept(str);
}
public static void main(String[] args) {
m1("helloworld",new Consumer<String>() {
@Override
public void accept(String t) {
System.out.println(t.length());
}
});
m1("helloworld",t -> System.out.println(t.length()));
}
}
java
// 供给型接口
public class Demo05 {
public static void m1(Supplier<Integer> supplier) {
System.out.println(supplier.get());
}
public static void main(String[] args) {
m1(new Supplier<Integer>() {
@Override
public Integer get() {
int sum = 0;
for(int i = 1;i<=10;i++) {
sum+=i;
}
return sum;
}
});
m1(() -> {
int sum = 0;
for(int i = 1;i<=10;i++) {
sum+=i;
}
return sum;
});
}
}
java
// 函数型接口
public class Demo06 {
// 定义一个方法,传入数组,得到数组的和
public static void m1(int[] arr,Function<int[], Integer> function) {
System.out.println(function.apply(arr));
}
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
m1(arr,new Function<int[], Integer>() {
@Override
public Integer apply(int[] t) {
int sum = 0;
for (int i : t) {
sum+=i;
}
return sum;
}
});
m1(arr,t -> {
int sum = 0;
for (int i : t) {
sum+=i;
}
return sum;
});
}
}
java
// 断言型接口
public class Demo07 {
// 测试一个数是不是7的倍数
public static void m1(int num,Predicate<Integer> predicate) {
System.out.println(predicate.test(num));
}
public static void main(String[] args) {
m1(7,new Predicate<Integer>() {
@Override
public boolean test(Integer t) {
return t % 7 == 0;
}
});
m1(7, t -> t % 7 == 0);
}
}
23.3Lambda简化
java
public class Demo08 {
public static void main(String[] args) {
m1("张三",t -> System.out.println(t));
// 简化写法
m1("张三",System.out::println);
m2("abcdefg",s -> s.toUpperCase());
// 简化写法
m2("abcdefg",String::toUpperCase);
m3( () -> Math.random() );
// 简化写法
m3(Math::random);
m4("张三",name -> new Student(name));
// 简化写法 使用一个参数的构造进行创建对象
m4("张三",Student::new);
}
// 传入一个名字,并打印
public static void m1(String name,Consumer<String> consumer) {
consumer.accept(name);
}
// 传入一个字符串,返回对应的大写
public static void m2(String str,Function<String, String> function) {
System.out.println(function.apply(str));
}
// 得到一个随机数
public static void m3(Supplier<Double> supplier) {
System.out.println(supplier.get());
}
// 输入name,得到一个Student对象
public static void m4(String name,Function<String, Student> function) {
System.out.println(function.apply(name));
}
}
23.4Stream流
流和集合类似,集合用于存储数据,而Stream用于对集合或者数组进行操作
特点:
Stream本身不存储数据,不会改变数据,有延迟操作,会等到有结果后再执行
步骤:
创建:获取一个新的流
中间操作:在一个或者多个步骤中,将初始的Stream转换为另一个Stream
终止操作:一个终止操作会产生一个结果
创建:
通过Collection对象的stream() paralletStream()
通过Arrays的Stream()
通过Stream自身的of() iterate() generate()
java
public class Demo09 {
public static void main(String[] args) {
m1();
m2();
m3();
}
public static void m1() {
List<String> list = new ArrayList<>();
list.add("zs");
list.add("ls");
list.add("ww");
// 创建Stream对象
Stream<String> stream = list.stream();
// stream.forEach(s -> System.out.println(s));
stream.forEach(System.out::println);
list.stream().forEach(System.out::println);
}
public static void m2() {
int[] arr = {1,2,3,4,5,6};
IntStream stream = Arrays.stream(arr);
stream.forEach(System.out::println);
}
public static void m3() {
// 直接使用值创建Stream对象
Stream<String> stream = Stream.of("zs","ls","ww");
stream.forEach(System.out::println);
}
}
java
// 中间操作
public class Demo10 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("111");
list.add("222");
list.add("333");
list.add("123123");
list.add("1235467");
list.add("12233311123");
list.add("111");
list.add("222");
// 正常输出
list.stream().forEach(System.out::println);
System.out.println("-------------------");
// 获取集合长度大于3的元素
list.stream().filter( li -> li.length() > 3).forEach(System.out::println);
System.out.println("-------------------");
// 获取前三条
list.stream().limit(3).forEach(System.out::println);
System.out.println("-------------------");
// 获取4-6
list.stream().skip(3)/*跳过前三*/.limit(3).forEach(System.out::println);
System.out.println("-------------------");
// 去除重复数据
list.stream().distinct().forEach(System.out::println);
System.out.println("-------------------");
// 排序
list.stream().sorted().forEach(System.out::println);
System.out.println("-------------------");
// 自定义排序
list.stream().sorted((a,b)->a.length() - b.length()).forEach(System.out::println);
}
}
java
// 终止操作
public class Demo11 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("111");
list.add("222");
list.add("333");
list.add("123123");
list.add("1235467");
list.add("12233311123");
list.add("111");
list.add("222");
// 正常输出
list.stream().forEach(System.out::println);
list.forEach(System.out::println);
System.out.println("-----------------------------");
Optional<String> max = list.stream().max((a,b) -> a.length() - b.length());
System.out.println(max.get());
Optional<String> min = list.stream().min((a,b) -> a.length() - b.length());
System.out.println(min.get());
long count = list.stream().filter(li -> li.length()>3).count();
System.out.println(count);
}
}
23.5新增时间API
java
public class Demo12 {
public static void main(String[] args) {
// 年月日时分秒毫秒
LocalDateTime now = LocalDateTime.now();
System.out.println(now);
// 年月日
LocalDate now2 = LocalDate.now();
System.out.println(now2);
now = LocalDateTime.of(2023, 12,27, 8,30);
System.out.println(now);
now2 = LocalDate.of(2020, 3, 20);
System.out.println(now2);
}
}