/
- Created by Manager on 2021/4/1.
- Java 8 新特性
- lambda表达式
- StreamAPI
- 新日期
- 新注解
*/
视频连接
1https://www.bilibili.com/video/BV1ut411g7E9
2https://www.bilibili.com/video/BV164411E7Ny?from=search&seid=476315511879331377
public interface TestInterface {
//语法糖
void testMethod();
}
class Godness {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Godness(String name) {
this.name = name;
}
public Godness() {
}
}
class myclass implements TestInterface {
public myclass() {
}
public myclass(String name) {
this.name = name;
}
public myclass(Optional<Godness> godness) {
this.godness = godness;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Optional<Godness> getGodness() {
return godness;
}
public void setGodness(Optional<Godness> godness) {
this.godness = godness;
}
// Optional
private Optional<Godness> godness = Optional.empty();
private String name;
private int age;
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
private Status status;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public enum Status {
Free,
BUSY,
VOCATION
}
@Override
public void testMethod() {
System.out.print("aaaaaaaaaaaaaaaa");
}
void doTest() {
//创建接口对象实现类
TestInterface test = new myclass();
test.testMethod();
//匿名内部类
TestInterface test2_ = new TestInterface() {
@Override
public void testMethod() {
System.out.print("bbbbb");
}
};
test2_.testMethod();
//lambda 接口的实现类的 具体对象 test2=====================
//{方法体中 只有一句 可省略}
//-> lambda操作符 goes to
//() 接口抽象方法 形参列表
//右边 接口抽象方法 方法体
//无参数 无返回值
TestInterface test3 = () -> System.out.print("lambda");
test3.testMethod();
//一个参数 无返回值 类型推断 int可省
//参数只有一个 ()可省
TestInterface3 test3_ = (x, y) -> x;
test3_.testMethod(1, 2);
//多参数 多代码(){} 不可省
TestInterface3 t3 = (x, y) -> {
return 2;
};
//只有return return 可省
TestInterface3 t3_ = (x, y) -> 20;
int a = t3_.testMethod(1, 2);
}
//lambda表达式使用的接口只能有一个抽象方法 ====函数式接口
//@FunctionalInterface 限定===》函数式接口 只有一个抽象函数
//一定是函数式接口
@FunctionalInterface
interface TestInterface3 {
int testMethod(int num1, int num2);
}
void dofour() {
String str = getString("aa", x -> x.toUpperCase());
op(100L, 100L, (x, y) -> x * y);
//==========================
//四个经常用内置的函数式 接口
//1 消费型接口 Consumer<T> void accept(T t)传递参数 无返回值
//2 供给型接口 Supplier<T> T get(); 无参数 返回 T
//3 函数型接口 Function<T,R> R apply(T t) T参数 返回 R
//4 断言型接口 Predicate<T> boolean test(T t)T参数 返回 boolean
// lambda中引用的参数 必须是常量fina 不可修改 默认加了 闭包中引用局部变量默认都是常量
Consumer<Double> consumer = x -> System.out.print("aaaaaaaaaaa" + x);
consumer.accept(1000.0);
Supplier<Integer> sup = () -> (int) (Math.random() * 100);//返回100内的随机数
Integer in = sup.get();
Function<String, String> fun1 = x -> x.trim();
String res = fun1.apply("1111");
Function<String, Integer> fun = x -> Integer.parseInt(x);
Integer res2 = fun.apply("1111");
Predicate<String> pre = x -> x.length() > 9;
Boolean bo = pre.test("101111");
//方法引用三种使用情况=============================
//lambda体中的内容有方法已经实现
//方法体的实现 引用指向一个已经实现的方法
//前面的 函数式接口 的 参数列表(数量 类型) 和返回值 和具体的实现方法体 的参数 和返回值 一致
// 可以使用方法引用
//1 对象:: 实例方法名 非静态
Consumer<String> con = x -> System.out.println("aaaaaaaaaaa" + x);
con.accept("1000.0");
Consumer<String> con2 = System.out::println;
con2.accept("aaaaaaaaaaa" + "1000.0");
//2 类 :: 静态方法名
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
int a = com.compare(10, 20);
Comparator<Integer> com2 = Integer::compare;
int a2 = com2.compare(10, 20);
//3 类 :: 实例方法名 x作为调用者 y为参数
BiPredicate<String, String> bp = (x, y) -> x.equals(y);
bp.test("nihao", "你好");
BiPredicate<String, String> bp2 = String::equals;
bp2.test("nihao", "你好");
//================================
// 构造器引用 className::new
// get()无参数 对应无参数构造器
// get() 一个参数对应构造器一个参数
Supplier<myclass> supplier = () -> new myclass();
Supplier<myclass> supplier2 = myclass::new;
myclass mc = supplier2.get();
Supplier<ArrayList> supplier3 = ArrayList::new;
List<String> list = supplier3.get();
Function<String, myclass> ff1 = x -> new myclass(x);
ff1.apply("wn1");
Function<String, myclass> ff2 = myclass::new;
myclass my = ff2.apply("wn2");
// 数组引用 Type::new
Function<Integer, String[]> f1 = x -> new String[x];
String[] strs = f1.apply(10);
Function<Integer, String[]> f2 = String[]::new;
String[] strs2 = f2.apply(10);
// 线程实例化 runnable 无参无返回值
Thread t = new Thread(()->{
});
t.start();
// Stream ====================
// 1原数据源(集合 数组) 不变 2转化成流Stream 3流水线式的中间操作 4终止操作 生成新的数据源(集合 数组)
// 1 创建Stream 2 中间操作 3终止操作
// 1 Collection系列集合提供的 stream()串行流 或者 parallelStream()并行流
List<String> list_s = new ArrayList<>();
list_s.add("11");
list_s.add("22");
list_s.add("33");
list_s.add("44");
list_s.removeIf(x -> x.length() > 4);//满足条件则删除
Stream<String> st = list_s.stream();
// 2 Stream中的静态方法Stream.of() 数组也可以
Stream<String> st1 = Stream.of("a", "b");
Stream<String> st11 = Stream.of(strs);
// 3 Arrays 中静态方法Arrays.stream()获取数组流
Stream<String> st2 = Arrays.stream(strs);
// 4 创建无限流
// 迭代
Stream<Integer> st3 = Stream.iterate(0, x -> x + 2);
st3.limit(5).forEach(System.out::println);
// 生成
Stream<Double> st4 = Stream.generate(() -> Math.random());
// 一 筛选与切片 ===========
// 1 排除 filter(Predicate<T>)
// 中间操作 不执行任何处理且没有任何结果
// 内部迭代 Stream API完成迭代
Stream<String> new1 = st.filter(x -> x.equals("11"));
// 终止才 执行全部内容且有结果 叫做 惰性求值
new1.forEach(System.out::println);
// 2 limit() 截断流 使元素不超过指定数量
// 只执行 目标数据操作 不执行其他 短路 2 只执行俩
// 3 skip(n) 跳过元素 扔掉前n个不要 执行后面的,总数不足n返回一个空流
// 4 distinct 筛选 通过流生成元素的 重写 hashCode()和equals()去除重复元素
new1.limit(1)
.skip(1)
.distinct()
.forEach(System.out::println);
// 二 映射 =================
// map 接受lambda 将元素转换成其他形式或者提取信息
// 将流中每一个元素 用在传递的函数上 生成新流
List<String> list2 = Arrays.asList("aa", "bb", "cc", "dd", "ee");
list2.stream().map(x -> x.toUpperCase()).forEach(System.out::println);
List<myclass> mylist = new ArrayList<>();
mylist.stream().map(myclass::getName);//提取信息
// flatMap 接收一个函数作为参数,将流中每一个值都转换为另一个流
// 然后把所有流都连城一个流
// list2.stream().map(x -> filterCharacter(x));
Stream<Stream<Character>> st_ch = list2.stream().map(myclass::filterCharacter);
st_ch.forEach(x -> x.forEach(System.out::println));
// flatMap map{{aaa},{bbb},{ccc}} flatMap{aaabbbccc}添加子流中元素所有流都连城一个流 最后变一个
// 类似 list中 add addAll
Stream<Character> st_ch2 = list2.stream().flatMap(myclass::filterCharacter);
// 三 排序======================
// sorted(Comparable) --自然排序 由小到大 字母顺序拍
list2.stream().sorted();
// sorted(Comparator com)--定制排序 指定条件 然后排序
mylist.stream().sorted((my1, my2) -> {
if (my1.getAge() == my2.getAge()) {
// 年龄相同按名字排
return my1.getName().compareTo(my2.getName());
} else {
// 不相同安年龄排 年龄降序my2.getAge()- my1.getAge()
return (my1.getAge() + "").compareTo((my2.getAge() + ""));
}
});
// 终止操作==============================
// 查找与匹配
// allMatch --检查是否匹配所有元素
// 全部都是 返回true
mylist.stream().allMatch(x -> x.getStatus().equals(Status.BUSY));
// anyMatch--检查是否至少匹配一个元素
// 有一个就可以 true
mylist.stream().anyMatch(x -> x.getStatus().equals(Status.BUSY));
// noneMatch--检查是否没有匹配所有元素
// 全部都不是 返回true
mylist.stream().noneMatch(x -> x.getStatus().equals(Status.VOCATION));
// findFirst--返回第一个元素 Optional 避免为空
Optional<myclass> myfirst = mylist.stream().sorted((my1, my2) -> Integer.compare(my1.getAge(), my2.getAge()))
.findFirst();
myclass myf = myfirst.get();
// findAndy--返回当前流中任意元素
Optional<myclass> myAny = mylist.stream().filter(x -> x.getStatus().equals(Status.Free))
.findAny();
// count--返回流中元素中和
long count = mylist.stream().count();
// max--返回流中最大值 类似 sorted(Comparator com)--定制排序 指定条件 然后排序
Optional<myclass> myMax = mylist.stream().max((my1, my2) -> Integer.compare(my1.getAge(), my2.getAge()));
// min--返回流中最小值
Optional<myclass> myMin = mylist.stream().min((my1, my2) -> Integer.compare(my1.getAge(), my2.getAge()));
// mylist.stream().map(myclass::getAge)
// .min((x,y) ->Integer.compare(x,y))
Optional<Integer> opInt = mylist.stream().map(myclass::getAge)
.min(Integer::compare);
int opi = opInt.get();
// 规约 reduce 将流中元素反复结合起来得到一个值
List<Integer> list3 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 0为起始值 1作为Y 0+ 1 然后 作为x 2作为y 继续到底
Integer sum = list3.stream().reduce(0, (x, y) -> x + y);
// mylist 中年龄总和
Integer allAge = mylist.stream().map(myclass::getAge).reduce(0, (x, y) -> x + y);
// 没有起始值 可能为空 所以返回Optional
Optional<Integer> allAge2 = mylist.stream().map(myclass::getAge).reduce((x, y) -> x + y);
Optional<Integer> allAge3 = mylist.stream().map(myclass::getAge).reduce(Integer::sum);
allAge3.get();
// 收集 collect 将流转换为其他形式 接受一个Collector接口 给Stream中元素做汇总
// 提取 名字 添加到集合中 collectors里面静态方法 Collectors.toList()
List<Integer> newList = mylist.stream().map(myclass::getAge).collect(Collectors.toList());
newList.forEach(System.out::println);
// set中
Set<String> newset = mylist.stream().map(myclass::getName).collect(Collectors.toSet());
// 生成指定的 类型
HashSet<String> newHashSet = mylist.stream().map(myclass::getName)
.collect(Collectors.toCollection(HashSet::new));
// 总数
long count2 = mylist.stream().collect(Collectors.counting());
// 平均值
Double aver = mylist.stream().collect(Collectors.averagingDouble(myclass::getAge));
// 总和
Double summ = mylist.stream().collect(Collectors.summingDouble(myclass::getAge));
// Double summ2 = mylist.stream().collect(Collectors.summingDouble(new ToDoubleFunction<myclass>() {
// @Override
// public double applyAsDouble(myclass value) {
// return value.getAge();
// }
// }));
Double summ3 = mylist.stream().map(myclass::getAge).collect(Collectors.summingDouble(x -> x));
// Double summ4 = mylist.stream().map(myclass::getAge).collect(Collectors.summingDouble
// (new ToDoubleFunction<Integer>() {
// @Override
// public double applyAsDouble(Integer value) {
// return value;
// }
// }));
// 最大值 orted(Comparator com)--定制排序 max min maxBy minBy
Optional<myclass> myMax_ = mylist.stream().max((my1, my2) -> Integer.compare(my1.getAge(), my2.getAge()));
Optional<myclass> myMax2 = mylist.stream().collect(Collectors.maxBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
// 最小值
Optional<Integer> myMMin2 = mylist.stream().map(myclass::getAge).collect(Collectors.minBy(Integer::compare));
// 分组 安状态分组
Map<Status, List<myclass>> map = mylist.stream().collect(Collectors.groupingBy(myclass::getStatus));
// 遍历map
// 多级分组
Map<Status, Map<String, List<myclass>>> map2 = mylist.stream().collect(Collectors.groupingBy(myclass::getStatus,
Collectors.groupingBy(x -> {
if (x.getAge() <= 35) {
return "青年";
} else if (x.getAge() <= 50) {
return "中年";
} else {
return "老年";
}
})));
// 分区 分为 true false 俩区
Map<Boolean, List<myclass>> map3 = mylist.stream().collect(Collectors.partitioningBy(x -> x.getAge() > 100));
// 另外一种方式获取
DoubleSummaryStatistics ss = mylist.stream().collect(Collectors.summarizingDouble(myclass::getAge));
ss.getSum();
ss.getAverage();
ss.getMax();
// 连接字符串
String str4 = mylist.stream().map(myclass::getName).collect(Collectors.joining());
// 连接字符串时加 ,
String str5 = mylist.stream().map(myclass::getName).collect(Collectors.joining(","));
// 连接字符串时加 , 头部加=== 尾部加===
String str6 = mylist.stream().map(myclass::getName)
.collect(Collectors.joining(",", "===", "==="));
//parallelStream 并行流
// 切换并行流parallel() 切换顺序流sequential()
LongStream.rangeClosed(0, 100000000L)
.parallel()
.reduce(0, Long::sum);
// Optional 类 避免空指针 快速锁定 null位置
Optional<myclass> op = Optional.of(new myclass());
myclass myop = op.get();
// of不能为空 empty()为空 ofNullable()参数不为空 创建of 为空 创建空empty
op.isPresent();//是否包含值 boolean
op.orElse(new myclass());//有值获取 没值 获取默认的new myclass()
myclass my4 = op.orElseGet(() -> new myclass());//有值获取 没值 获取默认的 函数式接口中的 new myclass()
Optional<String> name = op.map(myclass::getName);//有值 map处理 没有empty();
//flatMap 里面 function接口返回值必须是optional
Optional<String> flatop = op.flatMap(e -> Optional.ofNullable(e.getName()));
//避免空指针 每次 if判断
// Optional<myclass> op1 = Optional.ofNullable(null);
Optional<Godness> gd = Optional.ofNullable(new Godness("andy"));
Optional<myclass> op1 = Optional.ofNullable(new myclass(gd));
op1.orElse(new myclass())
//没有构造函数赋值 则是Optional empty
.getGodness()
.orElse(new Godness("aa"))
.getName();
//========================
// 全新的时间日期 API 之前的 线程不安全
// 1 LocalDate LocalTime LocalDateTime 人看的时间
LocalDateTime ldt = LocalDateTime.now();
LocalDateTime ldt2 = LocalDateTime.
of(2021, 10, 19, 13, 22, 33);
LocalDateTime ldt3 = ldt.plusYears(2);//加两年 新实例
ldt.minusMonths(2);//减俩月
ldt.getYear();//获取年
ldt.getMonthValue();//获取月
ldt.getDayOfMonth();//获取日
ldt.getHour();//获取时
ldt.getMinute();//获取分
ldt.getSecond();//获取秒
// 2 Instant 时间戳 1970年1月1号00:00:00 -现在毫秒值
Instant ins = Instant.now();//默认 UTC时区 跟中国差8 现在时间
ins.toEpochMilli(); //毫秒
OffsetDateTime ofd = ins.atOffset(ZoneOffset.ofHours(8));//偏移量运算
Instant.ofEpochSecond(60);//1970年1月1号00:00:00 加 60秒
// Duration 时间间隔
Instant ins2 = Instant.now();
Duration du = Duration.between(ins, ins2);
du.getSeconds();
du.toDays();
LocalTime ldt4 = LocalTime.now();
LocalTime ldt5 = LocalTime.now();
Duration du2 = Duration.between(ldt4, ldt5);
du2.toMillis();
// Period 日期之间的间隔
LocalDate ld = LocalDate.of(2015, 1, 1);
LocalDate ld2 = LocalDate.now();
Period pd = Period.between(ld, ld2);
pd.getMonths();
// TemporalAdjuster 时间矫正器
LocalDateTime ldt6 = LocalDateTime.now();
LocalDateTime ldt7 = ldt6.withDayOfMonth(10);//指定月为10月
ldt6.with(TemporalAdjusters.next(DayOfWeek.MONDAY));//指定下一个周一
//自定义 下一个工作日
ldt6.with(x -> {
LocalDateTime l = (LocalDateTime) x;
DayOfWeek day = l.getDayOfWeek();
if (day.equals(DayOfWeek.FRIDAY)) {
return l.plusDays(3);
} else if (day.equals(DayOfWeek.SATURDAY)) {
return l.plusDays(2);
} else {
return l.plusDays(1);
}
});
// DateTimeFormatter 格式化时间日期
LocalDateTime ldt8 = LocalDateTime.now();
DateTimeFormatter df = DateTimeFormatter.ISO_DATE_TIME;
String date = ldt8.format(df);
// 指定自己
DateTimeFormatter df2 = DateTimeFormatter.ofPattern("yyyy年MM月DD日HH:MM:SS");
String date2 = ldt8.format(df2);
// 字符串 to时间
LocalDateTime strdate = LocalDateTime.parse(date2, df2);
// 时区 指定时区
LocalDateTime ldt9 = LocalDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zdt = ldt9.atZone(ZoneId.of("Asia/Shanghai"));
//
}
interface MyFun3<T, U, R> {
public R getStr(T t1, U t2);
//default 默认方法
// 1 类优先原则 优先选择父类的同名方法 后接口中
// 2 实现多个接口 有同名 同参数方法 实现类中要明确是那个接口的
default String getName() {
return "aaaa";
}
// 静态方法
public static void show() {
}
}
public static Stream<Character> filterCharacter(String str) {
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
public String getString(String str, MyFun<String> myfun) {
return myfun.getStr(str);
}
private void op(Long a, Long b, MyFun2<Long, Long, Long> mf) {
mf.getStr(a, b);
}
}
//函数式 接口 只有一个抽象方法
@FunctionalInterface
interface MyFun<T> {
public T getStr(T t);
}
interface MyFun2<T, U, R> {
public R getStr(T t1, U t2);
}**