速度更快
代码更少(增加了新的语法Lambda表达式)
强大的Stream API
便于并行
最大化减少空指针异常Optional
package com.demo.zsq;
import org.junit.jupiter.api.Test;
import java.util.Comparator;
import java.util.function.Consumer;
/**
* 1.Lambda 表达式的基础语法:Java8中引入了一个新的操作符 ”->“ 该操作符称为箭头操作符 或 Lambda 操作符
* 箭头操作符将Lambda表达式拆分为两部分
* 左侧:Lambda 表达式的参数列表
* 右侧:Lambda 表达式中所需执行的功能,即 Lambda 体
*
* 语法格式1:无参数,无返回值
* ()-> System.out.println("Hello Lambda")
* 语法格式2:有参数,并且无返回值
* (x) -> System.out.println(x)
* 语法格式3:若只有一个参数,小括号可以省略不写
* x -> System.out.println(x)
* 语法格式4:有两个以上参数,有返回值,并且Lambda 体中有多条语句
* Comparator<Integer> com = (x,y) -> {
* System.out.println("是阿周呀");
* return Integer.compare(x,y);
* };
* 语法格式5:若Lambda体中只有一条语句,return 和 {} 都可以省略不写
* Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
* 语法格式6:表达式的参数列表的数据类型可以省略不写,因为JVM编译器通过上下文推断出,数据类型,即”类型推断“
* (Integer x,Integer y) -> Integer.compare(x,y);
*
* 2.Lambda表达式需要”函数式接口“的支持
* 函数式接口:接口中只有一个抽象方法的接口,称为函数式接口。可以使用注解 @FunctionalInterface 修饰
* 可以检查是否是函数式接口
*
*/
public class TestLambda2 {
@Test
public void test1(){
final int num = 0;//jdk 1.7之前,必须是final
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello Lambda"+num);
}
};
r.run();
System.out.println("------------------------------------");
Runnable r1 = () -> System.out.println("Hello Lambda");
r1.run();
}
@Test
public void test2(){
Consumer<String> con = (x) -> System.out.println(x);
con.accept("是阿周呀");
}
@Test
public void test3(){
Consumer<String> con = x -> System.out.println(x);
con.accept("是阿周呀");
}
@Test
public void test4(){
Comparator<Integer> com = (x,y) -> {
System.out.println("是阿周呀");
return Integer.compare(x,y);
};
}
@Test
public void test5(){
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
}
}
1.Lambda 表达式练习:
package com.demo.zsq;
public interface MyFunction2<T,R> {
public R getVlaue(T t1,T t2);
}
package com.demo.zsq;
import org.junit.jupiter.api.Test;
import java.util.*;
public class TestLeame {
List<Eempl> empls = Arrays.asList(
new Eempl("张三",11,"99999"),
new Eempl("A",11,"99999"),
new Eempl("C三",35,"99999"),
new Eempl("D三",11,"99999"),
new Eempl("E三",11,"99999")
);
@Test
public void test1(){
Collections.sort(empls,(e1,e2)->{
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}else{
return -Integer.compare(e1.getAge(),e2.getAge());
}
});
for (Eempl emp:empls){
System.out.println(emp);
}
}
@Test
public void test2(){
String str2 = strHandler("\t\t\t\t是阿周呀", (str) -> str.trim());
System.out.println(str2);
}
@Test
public void test3(){
op(100L,200L,(x,y) -> x + y);
op(100L,200L,(x,y) -> x * y);
}
//需求:对于两个Long型数据处理
public void op(Long l1,Long l2,MyFunction2<Long,Long> mf){
System.out.println(mf.getVlaue(l1,l2));
}
//需求:用于处理字符串
public String strHandler(String str,MyFunction mf){
return mf.getVlaue(str);
}
}
2.四大内置核心函数式接口:
package com.demo.zsq;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* Java8 内置的四大核心函数式接口
* Consumer<T>: 消费型接口
* void accept(T t);
* Supplier<T>: 供给型接口
* T get();
* Function<T,R>:函数型接口
* R apply(T t);
* Predicate<T> :断言型接口
* boolean test(T t);
*/
public class TestLembda {
//Predicate<T> :断言型接口
@Test
public void test4(){
List<String> list = Arrays.asList("1","a","b4444444","c","d","e","f");
List<String> strings = filterStr(list, (s) -> s.length() > 3);
for (String str:strings){
System.out.println(str);
}
}
//需求:将满足条件的字符串,放入集合中
public List<String> filterStr(List<String> list, Predicate<String> pre){
ArrayList<String> lists = new ArrayList<>();
for (String str: list){
if(pre.test(str)){
lists.add(str);
}
}
return lists;
}
// Function<T,R>:函数型接口
@Test
public void test3(){
String s = strHabdle("\t\t\t\t是啊周呀", (str) -> str.trim());
System.out.println(s);
String s1 = strHabdle("是啊周呀呀呀呀呀呀呀", (str) -> str.substring(2, 5));
System.out.println(s1);
}
//需求:用于处理字符串
public String strHabdle(String str, Function<String,String> fun){
return fun.apply(str);
}
//Supplier<T>: 供给型接口
@Test
public void test2(){
List<Integer> numsList = getNumList(10 ,() -> (int)(Math.random() * 100));
for (Integer num : numsList){
System.out.println(num);
}
}
//需求:产生指定个数的整数,并放入集合中
public List<Integer> getNumList(int num, Supplier<Integer> sup){
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < num; i++) {
Integer n = sup.get();
list.add(n);
}
return list;
}
//Consumer<T>: 消费型接口
@Test
public void test1(){
hepply(3000,(m) -> System.out.println("abcd"+m));
}
public void hepply (double moeny, Consumer<Double> con){
con.accept(moeny);
}
}
package com.demo.zsq;
import org.junit.jupiter.api.Test;
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.*;
/**
* 方法引用:若Leambda体中的内容有方法实现了,我们可以使用“方法引用”
* (可以理解为方法的引用是Lambda 表达式的另一种表现形式)
* 主要有三种语法格式:
* 对象::实例方法名
* 类:静态方法名
* 类:实例方法名
*
* 注意:
* ①Lambda体中调用方法的参数列表与返回值类型,要与函数式接口中抽象方法的函数列表和返回值类型保持一致!
*
* 构造器引用:
* 格式:
* ClassName:: new
*/
public class TestMethodRef {
//数组引用
@Test
public void test7(){
Function<Integer,String[]> fun =(x) -> new String[x];
String[] apply = fun.apply(10);
System.out.println(apply.length);
Function<Integer,String[]> fun2 = String[]::new;
String[] apply1 = fun2.apply(20);
System.out.println(apply1.length);
}
//构造器引用
@Test
public void test5(){
Supplier<Eempl> sup = () -> new Eempl();
//构造器引用方式
Supplier<Eempl> sup2 = Eempl::new;
Eempl eempl = sup2.get();
System.out.println(eempl);
}
/*@Test
public void test6(){
Function<Integer,Eempl> fun = (x) -> new Eempl();
Function<Integer,Eempl> fun2 = Eempl::new;
Eempl eempl = fun2.apply(102);
System.out.println(eempl);
}*/
//类:实例方法名
@Test
public void test4(){
BiPredicate<String ,String > bp = (x,y) -> x.equals(y);
BiPredicate<String,String> bp2 = String::equals;
}
//对象::实例方法名
@Test
public void test1(){
PrintStream ps1 = System.out;
Consumer<String> com = (x) -> ps1.println(x);
PrintStream ps = System.out;
Consumer<String> pres = ps::println;
Consumer<String> con2 = System.out::println;
con2.accept("abalfjdlfjoe");
}
@Test
public void tets2(){
Eempl eempl = new Eempl();
Supplier<String> sup = () -> eempl.getName();
String s = sup.get();
System.out.println(s);
Supplier<Integer> sups = eempl::getAge;
Integer integer = sups.get();
System.out.println(integer);
}
//类:静态方法名
@Test
public void test3(){
Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
Comparator<Integer> com1 = Integer::compare;
}
}
3.Java8新特性--->Stream
Java8中有两个最为重要的改变。第一个是Lambda表达式;另外一个则是Stream API(java.util.stream.*)
Stream是Java8中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL执行的数据库查询。也可以使用 Stream API 来并行执行操作,简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。
什么是Stream?
流(Stream)是什么呢?
是数据渠道,用于操作数据源(集合,数组等)所生成的元素序列。
“集合讲的是数据,流讲的是计算”
注意:
①Stream 自己不会存储元素
②Stream 不会改变源对象,相反,他们会返回一个持有结果的新Stream。
③Stream 操作是延迟执行的,这意味着他们会等到需要结果的时候才执行。
package com.demo.test;
import com.demo.zsq.Eempl;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
/**
* 操作Stream流的三步骤
* 1.创建Stream
* 2.中间操作
* 3.终止操作(终端操作)
*/
public class TestStreamApi2 {
List<Eempl> eemplList = Arrays.asList(
new Eempl("张三1",15,"111"),
new Eempl("张三2",18,"111"),
new Eempl("张三3",500002,"111"),
new Eempl("张三4",66,"111"),
new Eempl("张三5",33,"111")
);
/**
* 中间操作
* 筛选与切片
* filter-接收Lambda,从流中排除某些元素。
* limit-截断流,使其元素不超过给定数量。
* skip(n) 跳过元素,返回一个扔掉了前n个元素的流,若流中元素不足n个,则返回一个空流。与limit(n)互补
* distinct 筛选,通过流所生成的元素hashCode()和equals()去除重复元素
*/
@Test
public void test(){
//中间操作:不会执行任何操作
Stream<Eempl> stream = eemplList.stream()
.filter((e) -> {
System.out.println("Stream API的中间操作");
return e.getAge() > 35;
});
//终止操作:一次执行全部内容,即”惰性求值“
stream.forEach(System.out::println);
}
//外部迭代
@Test
public void test1(){
Iterator<Eempl> iterator = eemplList.iterator();
while(iterator.hasNext()){
System.out.println(iterator.hasNext());
}
}
//截断流
@Test
public void test2(){
eemplList.stream()
.filter((e) ->{
System.out.println("短路");// || &&
return e.getAge() > 5000;
})
.limit(2)
.forEach(System.out::println);
}
//筛选
@Test
public void test3(){
eemplList.stream()
.filter((e) -> e.getAge() > 5)
.skip(2)
.distinct()
.forEach(System.out::println);
}
}
映射:map接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。flatMap接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接池一个流。
package com.demo.test;
import com.demo.zsq.Eempl;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Stream;
/**
* 操作Stream流的三步骤
* 1.创建Stream
* 2.中间操作
* 3.终止操作(终端操作)
*/
public class TestStreamApi2 {
List<Eempl> eemplList = Arrays.asList(
new Eempl("张三1",15,"111"),
new Eempl("张三2",18,"111"),
new Eempl("张三3",500002,"111"),
new Eempl("张三4",66,"111"),
new Eempl("张三5",33,"111")
);
/*映射:map接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上
,并将其映射成一个新的元素。flatMap接收一个函数作为参数,将流中的每一个值都换成另一个流,然后把所有流连接池一个流。
*/
@Test
public void test4(){
List<String> list = Arrays.asList("aa","bb","cc","ddd");
list.stream()
.map((str) ->str.toUpperCase())
.forEach(System.out::println);
System.out.println("-----------------------------");
eemplList.stream()
.map(Eempl::getName)
.forEach(System.out::println);
System.out.println("-----------------------------");
Stream<Stream<Character>> streamStream = list.stream()
.map(TestStreamApi2::filterCharacter);
streamStream.forEach((sm) ->{
sm.forEach(System.out::println);
});
System.out.println("-----------------------------");
Stream<Character> sm = list.stream()
.flatMap(TestStreamApi2::filterCharacter);
sm.forEach(System.out::println);
}
@Test
public void test6(){
List<String> list = Arrays.asList("aa","bb","cc","dd");
List list1 = new ArrayList();
list1.add(11);
list1.add(22);
System.out.println(list1);
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()){
list.add(ch);
}
return list.stream();
}
}
4.Lambda——Stream:查找与匹配
查找与匹配 allMatch——检查是否匹配所有元素 anyMatch——检查是否至少匹配一个元素 noneMatch——检查是否没有匹配所有元素 findFirst——返回第一个元素 findAny——返回当前流中的任意元素 count——返回流中元素的总个数 max——返回流中最大值 min——返回流中最小值
package com.demo.test;
import com.demo.zsq.Eempl;
import org.junit.jupiter.api.Test;
import javax.swing.text.html.Option;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
/**
* 终止操作
*/
public class TestStreamApi3 {
/***
*查找与匹配
* allMatch——检查是否匹配所有元素
* anyMatch——检查是否至少匹配一个元素
* noneMatch——检查是否没有匹配所有元素
* findFirst——返回第一个元素
* findAny——返回当前流中的任意元素
* count——返回流中元素的总个数
* max——返回流中最大值
* min——返回流中最小值
*/
List<Eempl> eemplList = Arrays.asList(
new Eempl("张三1",15,"111", Eempl.Status.BUSY),
new Eempl("张三2",18,"111",Eempl.Status.BUSY),
new Eempl("张三3",500002,"111",Eempl.Status.VOCAITON),
new Eempl("张三4",66,"111",Eempl.Status.FREE),
new Eempl("张三5",33,"111",Eempl.Status.FREE)
);
@Test
public void test(){
boolean b1 = eemplList.stream()
.allMatch((e) -> e.getStatus().equals(Eempl.Status.BUSY));
System.out.println(b1);
boolean b2 = eemplList.stream()
.anyMatch((e) -> e.getStatus().equals(Eempl.Status.BUSY));
System.out.println(b2);
boolean b3 = eemplList.stream()
.noneMatch((e) -> e.getStatus().equals(Eempl.Status.BUSY));
System.out.println(b3);
Optional<Eempl> op =eemplList.stream()
.sorted((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge()))
.findFirst();
System.out.println(op.get());
Optional<Eempl> op2 = eemplList.parallelStream()
.filter((e) -> e.getStatus().equals(Eempl.Status.FREE))
.findAny();
System.out.println(op2.get());
}
@Test
public void test2(){
long count = eemplList.stream().count();
System.out.println(count);
Optional<Eempl> op1 = eemplList.stream()
.max((e1,e2) -> Integer.compare(e1.getAge(),e2.getAge()));
System.out.println(op1.get());
Optional<Integer> op2 = eemplList.stream()
.map(Eempl::getAge)
.min(Integer::compare);
System.out.println(op2.get());
}
}
归约:可以将流中元素反复结合起来,得到一个值
List<Eempl> eemplList = Arrays.asList(
new Eempl("张三1",15,"111", Eempl.Status.BUSY),
new Eempl("张三2",18,"111",Eempl.Status.BUSY),
new Eempl("张三3",500002,"111",Eempl.Status.VOCAITON),
new Eempl("张三4",66,"111",Eempl.Status.FREE),
new Eempl("张三5",33,"111",Eempl.Status.FREE)
);
/**
* 归约:
* reduce(T identity,BinaryOperator / reduce(BinaryOperator) —— 可以将流中元素反复结合起来,得到一个值)
*/
@Test
public void test3(){
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,10);
Integer sum = list.stream()
.reduce(0,(x, y) -> x + y);
System.out.println(sum);
System.out.println("----------------------------------------");
Optional<Integer> op = eemplList.stream()
.map(Eempl::getAge)
.reduce(Integer::sum);
System.out.println(op.get());
}
收集:
List<Eempl> eemplList = Arrays.asList(
new Eempl("张三1",15,29.5, Eempl.Status.BUSY),
new Eempl("张三1",18,28.5,Eempl.Status.BUSY),
new Eempl("张三3",500002,28.5,Eempl.Status.VOCAITON),
new Eempl("张三4",66,29.5,Eempl.Status.FREE),
new Eempl("张三5",33,277.5,Eempl.Status.FREE)
);
/**
* 收集:
* collect --将其转换为其他形式:接受一个Collector接口的实现,用于给Stream中的元素做汇总的方法
*/
@Test
public void test10(){
String collect = eemplList.stream()
.map(Eempl::getName)
.collect(Collectors.joining(",", "----", "==="));
System.out.println(collect);
}
@Test
public void test9(){
DoubleSummaryStatistics collect = eemplList.stream()
.collect(Collectors.summarizingDouble(Eempl::getSalary));
System.out.println(collect);
System.out.println(collect.getSum());
System.out.println(collect.getAverage());
System.out.println(collect.getMax());
System.out.println(collect.getMin());
System.out.println(collect.getCount());
}
//分区
@Test
public void test8(){
Map<Boolean,List<Eempl>> map = eemplList.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() > 8000));
System.out.println(map);
}
//多级分组
@Test
public void test7(){
Map<Eempl.Status,Map<String,List<Eempl>>> map = eemplList.stream()
.collect(Collectors.groupingBy(Eempl::getStatus,Collectors.groupingBy((e) ->{
if(((Eempl) e).getAge() <= 35){
return "青年";
}else if(((Eempl) e).getAge() <= 50) {
return "中年";
}else{
return "老年";
}
})));
System.out.println(map);
}
//分组
@Test
public void tet6(){
Map<Eempl.Status,List<Eempl>> map = eemplList.stream()
.collect(Collectors.groupingBy(Eempl::getStatus));
System.out.println(map);
}
@Test
public void test5(){
//总和
Long count = eemplList.stream()
.collect(Collectors.counting());
System.out.println(count);
//平均值
Double collect = eemplList.stream()
.collect(Collectors.averagingDouble(Eempl::getSalary));
System.out.println(collect);
//总数 + 总和 + 最小值 + 平均值 + 最大值
DoubleSummaryStatistics sum = eemplList.stream()
.collect(Collectors.summarizingDouble(Eempl::getSalary));
System.out.println(sum);
//最大值
Optional<Eempl> max = eemplList.stream()
.collect(Collectors.maxBy((e1,e2) -> Double.compare(e1.getSalary(),e2.getSalary())));
System.out.println(max.get());
//最小值
Optional<Double> min =eemplList.stream()
.map(Eempl::getSalary)
.collect(Collectors.minBy(Double::compare));
System.out.println(min.get());
}
5.Stream-API练习:
package com.demo.exe;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class TestTransaction {
List<Transaction> transactions = null;
@Before
public void before(){
Trader trader = new Trader("啊歪", "耒阳");
Trader trader1 = new Trader("周周", "长沙");
Trader trader2 = new Trader("阿华", "衡阳");
Trader trader3 = new Trader("阿雷", "怀化");
Trader trader4 = new Trader("阿娟", "安化");
transactions = Arrays.asList(
new Transaction(trader,2011,300),
new Transaction(trader1,2012,430),
new Transaction(trader3,2012,580),
new Transaction(trader2,2011,1000),
new Transaction(trader4,2011,950)
);
}
//1.找出2011年发生的所有交易 ,并按交易额排序(从低到高)
@Test
public void test1(){
transactions.stream()
.filter((t) -> t.getYear() == 2011)
.sorted((t1,t2) -> Integer.compare(t1.getValue(),t2.getValue()))
.forEach(System.out::println);
}
//2.交易员都在哪些不同的城市工作过?
@Test
public void test2(){
transactions.stream()
.map((t) -> t.getTrader().getCity())
.distinct()
.forEach(System.out::println);
}
//3.查找所有来自长沙的交易员,并按姓名排序
@Test
public void test3(){
transactions.stream()
.filter((t) -> t.getTrader().getCity().equals("长沙"))
.map(Transaction::getTrader)
.sorted((t1,t2) -> t1.getName().compareTo(t2.getName()))
.distinct()
.forEach(System.out::println);
}
//4.返回所有交易员的姓名字符串,按字母顺序排序
@Test
public void test4(){
transactions.stream()
.map((t)-> t.getTrader().getName())
.sorted()
.forEach(System.out::println);
System.out.println("-------------------------------------------");
String str = transactions.stream()
.map((t) -> t.getTrader().getName())
.sorted()
.reduce("",String::concat);
System.out.println(str);
System.out.println("--------------------------------------------");
transactions.stream()
.map((t)->t.getTrader().getName())
.flatMap(TestTransaction::filterCharater)
.sorted()
.forEach(System.out::print);
System.out.println("--------------------------------------------");
transactions.stream()
.map((t) -> t.getTrader().getName())
.flatMap(TestTransaction::filterCharater)
.sorted((s1,s2) ->s1.compareToIgnoreCase(s2))
.forEach(System.out::print);
}
public static Stream<String> filterCharater(String str){
List<String> list = new ArrayList<>();
for (Character ch:str.toCharArray()){
list.add(ch.toString());
}
return list.stream();
}
//5.有没有交易员是在长沙工作的?
@Test
public void test5(){
boolean b = transactions.stream()
.anyMatch((t) -> t.getTrader().getCity().equals("长沙"));
System.out.println(b);
}
//6.打印生活在耒阳的交易员的所有交易额
@Test
public void test6(){
Optional<Integer> sum = transactions.stream()
.filter((e) -> e.getTrader().getCity().equals("耒阳"))
.map(Transaction::getValue)
.reduce(Integer::sum);
System.out.println(sum.get());
}
//7.所有交易中,最高的交易额是多少
@Test
public void test7(){
Optional<Integer> max = transactions.stream()
.map((t) -> t.getValue())
.max(Integer::compare);
System.out.println(max.get());
}
//8.找到交易额最小的交易
@Test
public void test8(){
Optional<Transaction> op = transactions.stream()
.min((t1,t2) -> Integer.compare(t1.getValue(),t2.getValue()));
System.out.println(op.get());
}
}
6.并行流和顺序流:
package com.demo.fock;
import com.demo.zsq.Eempl;
import org.junit.jupiter.api.Test;
import java.util.Optional;
public class TestOptional {
/**
* Optional 容器类的常用方法:
* Optional.of(T t) :创建一个Opational 实例
* Optional.emptu() :创建一个空的Optional 实例
* Optional.ofNullable(T t):若 t不为null,创建Opational实例,否则创建空实例
* isPresent():判断是否包含值
* orElse(T t):如果调用对象包含值,返回该值,否则返回t
* orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
* map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
* flatMap(Function mapper):与map类似,要求返回值必须是Optional
*/
@Test
public void test4(){
Optional<Eempl> op = Optional.ofNullable(new Eempl("张三",18,18.9, Eempl.Status.BUSY));
/* Optional<String> s = op.map((e) -> e.getName());
System.out.println(s.get());*/
Optional<String> str2 = op.flatMap((e) ->Optional.of(e.getName()));
System.out.println(str2.get());
}
@Test
public void test3(){
Optional<Eempl> op = Optional.ofNullable(new Eempl());
if(op.isPresent()){
System.out.println(op.get());
}
op.orElse(new Eempl("张三",19,88.9, Eempl.Status.BUSY));
System.out.println(op.get());
}
@Test
public void test2(){
Optional<Eempl> op = Optional.empty();
System.out.println(op.get());
}
@Test
public void tets1(){
Optional<Eempl> op = Optional.ofNullable(null);
Eempl eempl = op.get();
System.out.println(eempl);
}
@Test
public void test6(){
Optional<Godenee> ge = Optional.ofNullable(new Godenee("宝宝"));
Optional<newMan> op = Optional.ofNullable(new newMan(ge));
String goodssName2 = getGoodssName2(op);
System.out.println(goodssName2);
}
public String getGoodssName2(Optional<newMan> newman){
return newman.orElse(new newMan())
.getGodenee()
.orElse(new Godenee("周周"))
.getName();
}
@Test
public void test5(){
Man man = new Man();
String godenee = getGoodssName(man);
System.out.println(godenee);
}
public String getGoodssName(Man man){
if(man != null){
Godenee godenee = man.getGodenee();
if(godenee != null){
return godenee.getName();
}
}
return "周周";
}
}
package com.demo.fock;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Man {
private Godenee godenee;
}
package com.demo.fock;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import java.util.Optional;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class newMan {
private Optional<Godenee> godenee = Optional.empty();
}
package com.demo.fock;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Godenee {
private String name;
}
7.接口中的默认方法
package com.demo.gtgui;
public interface MyFun {
default String getName(){
return "哈哈哈哈";
}
}
package com.demo.gtgui;
public class MyClass {
public String getName(){
return "嘿嘿";
}
}
package com.demo.gtgui;
public class SubClass extends MyClass implements MyFun{
}
package com.demo.gtgui;
public class TestDefaultInterface {
public static void main(String[] args) {
SubClass subClass = new SubClass();
System.out.println(subClass.getName());
}
}
———————————————————————————————————————————
package com.demo.gtgui;
public class SubClass implements MyFun,MyInterface{
@Override
public String getName() {
return MyFun.super.getName();
}
}
package com.demo.gtgui;
public interface MyInterface {
static void show(){
System.out.println("接口中的静态方法");
}
default String getName(){
return "呵呵呵";
}
}
package com.demo.gtgui;
public class TestDefaultInterface {
public static void main(String[] args) {
SubClass subClass = new SubClass();
System.out.println(subClass.getName());
MyInterface.show();
}
}
8.传统时间格式的线程安全问题
1.传统时间格式的线程安全
package com.demo.gtgui;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
public class TestimpleDateFormat {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Date> task = new Callable<Date>() {
@Override
public Date call() throws Exception {
return DateFormatThreadLocal.convert("20161218");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<Date>> resulter = new ArrayList<>();
for (int i = 0; i < 10; i++) {
resulter.add(pool.submit(task));
}
for (Future<Date> future : resulter){
System.out.println(future.get());
}
}
}
package com.demo.gtgui;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateFormatThreadLocal {
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){
protected DateFormat initialValue(){
return new SimpleDateFormat("yyyyMMdd");
}
};
public static Date convert(String source) throws ParseException{
return df.get().parse(source);
}
}
2.新的时间格式的线程安全
public static void main(String[] args) throws ExecutionException, InterruptedException {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
Callable<LocalDate> task = new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("20161218",dtf);
}
};
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> resulter = new ArrayList<>();
for (int i = 0; i < 10; i++) {
resulter.add(pool.submit(task));
}
for (Future<LocalDate> future : resulter){
System.out.println(future.get());
}
}
9.新时间格式API
package com.demo.dataTime;
import org.junit.jupiter.api.Test;
import java.time.*;
public class TestLocalDateTime {
//1.LocalDate LocalTime LocalDateTime
@Test
public void test(){
//获取系统当前时间
LocalDateTime now = LocalDateTime.now();
System.out.println(now);//2022-12-04T14:10:28.526
//拿到指定的时间
LocalDateTime of = LocalDateTime.of(2015, 11, 23, 10, 9, 20);
System.out.println(of);
//根据当前时间加上两年之后的值
LocalDateTime localDateTime = now.plusYears(2);
System.out.println(localDateTime);
//根据当前时间减去两个月的值
LocalDateTime localDateTime1 = now.minusMonths(2);
System.out.println(localDateTime1);
System.out.println(now.getYear());//年
System.out.println(now.getMonthValue());//月
System.out.println(now.getDayOfMonth());//日
System.out.println(now.getHour());//时
System.out.println(now.getMinute());//分
System.out.println(now.getSecond());//秒
}
//2. Instant : 时间戳(以Unix元年:1970年1月1日 00:00:00 到某个时间之间的毫秒值)
@Test
public void test2(){
Instant now = Instant.now();//默认获取 UTC 时区
System.out.println(now);
OffsetDateTime offer = now.atOffset(ZoneOffset.ofHours(8));//待偏移量的时间+8小时
System.out.println(offer);
System.out.println(now.toEpochMilli());//毫秒时间
Instant instant = Instant.ofEpochSecond(60);//获取到元年1970年1月1日的基础上+60秒
System.out.println(instant);
}
//3.Duration :计算两个”时间“之间的间隔
// Period : 计算两个”日期“之间的间隔
@Test
public void test3(){
Instant now = Instant.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Instant now1 = Instant.now();
Duration between = Duration.between(now, now1);
System.out.println(between.toMillis());
System.out.println("------------------------------------------------------");
LocalTime now2 = LocalTime.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
LocalTime now3 = LocalTime.now();
System.out.println(Duration.between(now2, now3).toMillis());
}
@Test
public void test4(){
LocalDate of = LocalDate.of(2021, 9, 2);
LocalDate now = LocalDate.now();
Period between = Period.between(of, now);
System.out.println(between);
System.out.println(between.getYears());
System.out.println(between.getMonths());
System.out.println(between.getDays());
}
}
package com.demo.dataTime;
import org.junit.jupiter.api.Test;
import java.text.DateFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
public class TestNewDateTime {
//TemporalAdjuster : 时间校正器
@Test
public void test(){
LocalDateTime now = LocalDateTime.now();
System.out.println(now);//2022-12-04T15:00:14.326
LocalDateTime localDateTime = now.withDayOfMonth(10);
System.out.println(localDateTime);//2022-12-10T15:00:14.326
LocalDateTime with = now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));//根据当前时间找到下一个星期的星期天
System.out.println(with);//2022-12-11T15:00:14.326
//自定义下一个工作日
LocalDateTime ldt5 = now.with((n) ->{
LocalDateTime ldt4 = (LocalDateTime) n;
DayOfWeek dow = now.getDayOfWeek();
if(dow.equals(DayOfWeek.FRIDAY)){
return ldt4.plusDays(3);
}else if(dow.equals(DayOfWeek.SATURDAY)){
return ldt4.plusDays(2);
}else{
return ldt4.plusDays(1);
}
});
System.out.println(ldt5);
}
}
DateTimeFormatter : 格式化时间/日期
package com.demo.dataTime;
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
public class DateTimeFormatter2 {
//DateTimeFormatter : 格式化时间/日期
@Test
public void test(){
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime now = LocalDateTime.now();
String format = now.format(dtf);
System.out.println(format);//2022-12-04T15:21:46.135
System.out.println("------------------------------------------");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
String format1 = dateTimeFormatter.format(now);
System.out.println(format1);//2022年12月04日 15:21:46
LocalDateTime newDate = now.parse(format1,dateTimeFormatter);
System.out.println(newDate);//2022-12-04T15:28:45
}
}
//ZonedDate ZonedTime ZonedDateTime
@Test
public void test2(){
Set<String> set = ZoneId.getAvailableZoneIds();//可支持的时区
set.forEach(System.out::println);
}
@Test
public void test3(){
LocalDateTime loca = LocalDateTime.now(ZoneId.of("Europe/Tallinn"));
System.out.println(loca);//2022-12-04T09:36:37.713
LocalDateTime loca2 = LocalDateTime.now();
ZonedDateTime zonedDateTime = loca2.atZone(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zonedDateTime1 = loca2.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zonedDateTime1);//2022-12-04T15:42:41.598+08:00[Asia/Shanghai]
}
package com.demo.dataTime;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
@Repeatable(MyAnnotation2.class)
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE,TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value() default "atguigu";
}
package com.demo.dataTime;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
@Target({TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation2 {
MyAnnotation[] value();
}
package com.demo.dataTime;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
/**
* 重复注解与类型注解
*/
public class TestAnnotation {
@Test
public void test1() throws NoSuchMethodException {
Class<TestAnnotation> clazz = TestAnnotation.class;
Method show = clazz.getMethod("show");
MyAnnotation[] ms = show.getAnnotationsByType(MyAnnotation.class);
for (MyAnnotation myAnnotation : ms){
System.out.println(myAnnotation.value());
}
}
@MyAnnotation("hello")
@MyAnnotation("World")
public void show(@MyAnnotation("abcdd") String str){
}
}