Java8新特性 -- 函数式编程
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Test;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
public class TestLambda {
/**
* 验证:对比使用lambda
**/
@Test
public void test1() throws InterruptedException {
new Thread(
new Runnable() {
@Override
public void run() {
System.out.println("不使用Lambda");
}
}
).start();
new Thread(() -> System.out.println("使用Lambda")).start();
Thread.sleep(2000);
}
/**
* 验证:Lambda与方法的对比
**/
@Test
public void test2(){
/**
(参数类型 参数名称) -> {
代码体;
}
public void run(){
System.out.print("aa");
}
() -> {System.out.print("aa");}
*/
}
/**
* 验证:函数式接口的使用
**/
@Test
public void test3(){
int[] arr = {1,23,12,42};
//常规
getSum(arr, new Operator() {
@Override
public int sum(int[] arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
});
//函数式
getSum(arr,(int[] s) -> {
int sum = 0;
for (int i : s) {
sum += s[i];
}
return sum;
});
}
public static void getSum(int[] arr,Operator operator){
int sum = operator.sum(arr);
System.out.println("sum="+sum);
}
/**
* 验证:常用内置函数时接口 - Supplier
**/
@Test
public void testSupplier(){
//对外提供一个符合泛型类型的对象数据
int[] arr = {1,23,12,42};
getMax(()->{
Arrays.sort(arr);
return arr[arr.length - 1];
});
}
public static void getMax(Supplier<Integer> supplier){
Integer max = supplier.get();
System.out.println("max="+max);
}
/**
* 验证:Consumer接口
**/
@Test
public void testConsumer(){
String str = "Hello World!";
changeTheWord(str,(String s)->{
System.out.println(s.toLowerCase());
});
}
public static void changeTheWord(String word,Consumer<String> consumer){
consumer.accept(word);
}
/**
* 验证:Consumer的andThen方法
**/
@Test
public void testConsumerAndThen(){
consumerAndThen(
"Hello World",
(String s)->{
System.out.println(s.toLowerCase());},
(String s)->{
System.out.println(s.toUpperCase());
}
);
}
public static void consumerAndThen(String str,Consumer<String> c1,Consumer<String> c2){
//普通写法:按顺序处理字符串
/*c1.accept(str);
c2.accept(str);*/
//andThen写法:按顺序处理字符串
c1.andThen(c2).accept(str);
}
/**
* 验证:Function方法 -- 接收参数,处理后返回对应类型的值
**/
@Test
public void testFunction(){
//将String转成int
intToString("99", (String str)->{return Integer.parseInt(str) + 5;});
}
public static void intToString(String i, Function<String,Integer> function){
Integer apply = function.apply(i);
System.out.println(apply);
}
/**
* 验证:Function接口的andThen方法
**/
@Test
public void testFunctionAndThen(){
functionAndThen("99",
(String s)->{
return Integer.parseInt(s);
},
(Integer i)->{
return i*10;
}
);
}
public static void functionAndThen(String str, Function<String,Integer> f1, Function<Integer,Integer> f2){
//普通写法:先把String转成Integer,再把前面的结果乘以10
/*Integer apply = f1.apply(str);
Integer apply1 = f2.apply(apply);
System.out.println(apply1);*/
//andThen写法:先把String转成Integer,再把前面的结果乘以10
f1.andThen(f2).apply(str);
}
/**
* 验证:Predicate接口
**/
@Test
public void testPredicate(){
isLongName("倚天屠",(String s)->{
int length = StrUtil.length(s);
if (length > 3){
System.out.println("名字过长");
return true;
}
return false;
});
}
public static void isLongName(String name,Predicate<String> predicate){
predicate.test(name);
}
/**
* 验证:Predicate接口的或、与、非方法
**/
@Test
public void testPredicateAndOrNot(){
andOrNot("o",
(String s)->{return s.contains("W");},
(String s)->{return s.contains("h");}
);
}
public static void andOrNot(String str,Predicate<String> p1,Predicate<String> p2){
//and
boolean test = p1.and(p2).test(str);
if (test) System.out.println("同时满足");
//or
boolean test1 = p1.or(p2).test(str);
if (test1) System.out.println("满足其一");
//not
boolean test2 = p1.negate().test(str);
if (test2) System.out.println("不满足");
}
/**
* 验证:计算数组中参数的和 -- 方法引用
**/
@Test
public void testSumArr(){
int[] arr = {1,3,45,12,2};
//正常写法
sum(arr,(int[] s)->{
int sum = 0;
for (int i : s) {
sum += i;
}
System.out.println(sum);
});
//引用写法,引用已经存在的相同方法,
sum(arr,TestLambda::getSum);
}
public static void sum(int[] arr,Consumer<int[]> consumer){
consumer.accept(arr);
}
public static void getSum(int[] arr){
int sum = 0;
for (int i : arr) {
sum += i;
}
System.out.println(sum);
}
/**
* 验证:对象名::引用成员方法
**/
@Test
public void testObjectMethodQuote(){
Date date = new Date();
//传统写法
Supplier<Long> supplier = ()->{return date.getTime();};
System.out.println(supplier.get());
//对象::引用成员方法
Supplier<Long> supplier1 = date::getTime;
System.out.println(supplier1.get());
}
/**
* 验证:类名::引用静态方法
**/
@Test
public void testClassNameStaticMethod(){
Supplier<Long> supplier = ()->{return System.currentTimeMillis();};
System.out.println(supplier.get());
Supplier<Long> supplier1 = System::currentTimeMillis;
System.out.println(supplier1.get());
}
/**
* 验证:类名::引用实例方法
**/
@Test
public void testClassNameInstanceMethod(){
Function<String, Integer> function = (String s)->{return s.length();};
Function<String,Integer> f2 = String::length;
}
/**
* 验证:类名::构造方法
**/
@Test
public void testClassNameConstructMethod(){
Supplier<Person> supplier = Person::new;
}
/**
* 验证:类型[]:new
**/
@Test
public void testArrayNew(){
Supplier<String[]> supplier = ()->new String[0];
//两种写法
Function<Integer,String[]> function = (Integer i)->{return new String[i];};
Function<Integer,String[]> function2 = String[]::new;
String[] apply = function.apply(5);
System.out.println(apply.length);
}
/**
* 验证:StreamFilter
**/
@Test
public void testStreamFilter(){
ArrayList<String> list = CollectionUtil.newArrayList("ABC","BCD","EF","AB","ACD");
list.stream()
.filter((String s)->{return s.startsWith("A");})
.filter((String s)->{return s.length() == 2;})
.forEach((String s)->{
System.out.println(s);
});
}
/**
* 验证:获取流 -- Collection接口通过stream方法获取
**/
@Test
public void testGetCollectionStream(){
ArrayList<Object> list = new ArrayList<>();
list.stream();
HashSet<Object> set = new HashSet<>();
set.stream();
Vector<Object> vector = new Vector<>();
vector.stream();
}
/**
* 验证:获取流 -- Map
**/
@Test
public void testGetMapStream(){
HashMap<String, String> map = new HashMap<>();
Stream<String> keyStream = map.keySet().stream();
Stream<String> valueSet = map.values().stream();
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();
}
/**
* 验证:获取流 -- 数组对象使用静态方法of()
**/
@Test
public void testGetArrStream(){
Stream<String> a = Stream.of("a", "b");
a.forEach(s-> System.out.println(s));
String[] strArr = {"a","b"};
Stream<String> b = Stream.of(strArr);
b.forEach(s-> System.out.println(s));
//基本数据类型,无法转化为stream
int[] intArr = {11,23,3};
Stream<int[]> intArr1 = Stream.of(intArr);
for (int i : intArr) {
System.out.println(i);
}
}
/**
* 验证:Stream流的foreach方法
**/
@Test
public void testStreamForEach(){
ArrayList<String> strList = CollectionUtil.newArrayList("a", "ab", "ca", "abda");
strList.stream().forEach((String s)->{System.out.println(s);});
}
/**
* 验证:Stream流的count方法
**/
@Test
public void testStreamCount(){
ArrayList<String> strList = CollectionUtil.newArrayList("a", "ab", "ca", "abda");
System.out.println(strList.stream().count());
}
/**
* 验证:Stream流的limit / skip方法,截取元素
**/
@Test
public void testStreamLimit(){
ArrayList<String> strList = CollectionUtil.newArrayList("a", "ab", "ca", "abda");
//List<String> collect = strList.stream().limit(2).collect(Collectors.toList());
strList.stream().limit(2).forEach((String s)->{System.out.println(s);});
strList.stream().skip(2).forEach((String s)->{System.out.println(s);});
}
/**
* 验证:Stream流的Map方法
* 将流中的元素映射到另一个流中
**/
@Test
public void testStreamMap(){
Stream<String> stream = Stream.of("1", "34", "22");
stream.map((String s)->{return Integer.parseInt(s)*10;}).forEach((Integer i)->{System.out.println(i);});
}
/**
* 验证:Stream流中的sorted方法
* 排序
**/
@Test
public void testStreamSorted(){
Stream<Integer> intStream = Stream.of(1, 334, 211, 90, 32, 87);
//默认按大小规则排序
//intStream.sorted().forEach(System.out::println);
//自定义排序规则
intStream.sorted((Integer i1,Integer i2)-> {return i2-i1;}).forEach((Integer i)->{System.out.println("自定义规则:"+i);});
}
/**
* 验证:Stream流的distinct方法,自定义对象根据equals和hashCode来去重
**/
@Test
public void testStreamDistinct(){
Stream<Integer> intStream = Stream.of(1, 334, 211, 90, 211, 1);
intStream.distinct().forEach(System.out::println);
}
/**
* 验证:Stream流的match方法
**/
@Test
public void testStreamMatch(){
Stream<Integer> intStream = Stream.of(1, 334, 211, 90, 211, 1);
boolean b = intStream
//.anyMatch
//.allMatch
.noneMatch
((Integer i) -> {
return i > 100;
});
System.out.println(b);
}
/**
* 验证:Stream流的find方法
**/
@Test
public void testStreamFind(){
Stream<Integer> intStream = Stream.of(334, 211, 90, 211, 1);
Optional<Integer> any = intStream.parallel().findAny();
System.out.println("any="+any.get());
}
/**
* 验证:Stream流的max/min方法
**/
@Test
public void testStreamMax(){
Stream<Integer> intStream = Stream.of(334, 211, 90, 211, 1);
/* Optional<Integer> max = intStream.max((Integer i1,Integer i2)->{return i1 - i2;});
System.out.println("max="+max.get());*/
Optional<Integer> min = intStream.min((Integer i1,Integer i2)->{return i1 - i2;});
System.out.println("min="+min.get());
}
/**
* 验证:Stream流的reduce方法
* Sum, min, max, average, and string concatenation are all special cases of reduction
* * <pre>{@code
* * T result = identity;
* * for (T element : this stream)
* * result = accumulator.apply(result, element)
* * return result;
* * }</pre>
**/
@Test
public void testStreamReduce(){
Stream<Integer> intStream = Stream.of(334, 211, 90, 211, 1);
// 累加操作
Integer reduce = intStream.reduce(0, (Integer a, Integer b) -> {
return a + b;
});
System.out.println("reduce="+reduce);
// 找最大值操作
Optional<Integer> max = intStream.reduce((Integer a, Integer b) -> {
if (a < b) {
return a;
}
return b;
});
System.out.println("最大值="+max.get());
}
/**
* 验证:map和reduce组合使用
**/
@Test
public void testMapAndReduce(){
Stream<Person> personStream = Stream.of(
new Person("a",12),
new Person("b",33),
new Person("c",26)
);
//所有年龄的总和
Integer ageSum = personStream
.map((Person p) -> {
return p.getAge();
})
.reduce(0, (Integer a, Integer b) -> {
return a + b;
});
System.out.println("年龄总和="+ageSum);
//找出年龄最大的
Stream<Person> personStream2 = Stream.of(
new Person("a",12),
new Person("b",33),
new Person("c",26)
);
Optional<Integer> maxAge = personStream2
.map((Person p) -> {
return p.getAge();
})
.reduce((Integer a, Integer b) -> {
if (a > b) {
return a;
}
return b;
});
System.out.println(maxAge.get());
//统计数字2出现的次数
Stream<Integer> integerStream = Stream.of(2, 34, 2, 42, 4, 6, 2);
Integer times = integerStream
.map((Integer a)->{
if (a == 2){
return 1;
}
return 0;
}).reduce(0,(Integer a,Integer b)->{
return a+b;
});
System.out.println("2出现的次数="+times);
}
/**
* 验证:Stream的mapToInt方法
**/
@Test
public void testMapToInt(){
Stream<Integer> stream = Stream.of(new Integer[]{1, 2, 4, 4, 3, 2, 0});
// 把大于3的和打印出来
/*Integer sum = stream
.filter((Integer i) -> {
return i > 3;
})
.reduce(0, (Integer a, Integer b) -> {
return a + b;
});
System.out.println(sum);*/
// Integer占用的内存比int多,Stream流操作中会自动装箱和拆箱,以下为解决方案
IntStream intStream = stream.mapToInt((Integer i) -> i.intValue());
int sum2 = intStream.filter(i -> i > 3).reduce(0, (int a, int b) -> {
return a + b;
});
System.out.println(sum2);
// 将intStream转化为Stream<Integer>
IntStream intStream1 = IntStream.rangeClosed(1, 10);
Stream<Integer> boxed = intStream1.boxed();
boxed.forEach((Integer i)->{System.out.println(i.getClass() + ", "+ i);});
}
/**
* 验证:Stream的concat方法
**/
@Test
public void testStreamConcat(){
Stream<String> a = Stream.of("a", "b");
Stream<String> c = Stream.of("C", "D");
Stream<String> concat = Stream.concat(a, c);
concat.forEach(System.out::println);
}
/**
* 验证:综合案例
**/
@Test
public void testSummary(){
ArrayList<String> list1 = CollectionUtil.newArrayList("迪丽热巴", "宋远桥", "苏星河", "老子", "庄子", "孙子", "洪七公");
ArrayList<String> list2 = CollectionUtil.newArrayList("古力娜扎", "张无忌", "张三丰", "赵丽颖", "张二狗", "张天爱", "张三");
//队伍1: 名字为3个字 && 只要前三个
Stream<String> a = list1.stream().filter((String s) -> {
return s.length() == 3;
}).limit(3);
//队伍2: 只要张姓成员 && 不要前两个人
Stream<String> b = list2.stream().filter(s -> s.startsWith("张")).skip(2);
//合并队伍 && 根据姓名创建Person对象 && 打印整个队伍的Person信息
Stream.concat(a,b).map((String name)->{return new Person(name);}).forEach(System.out::println);
}
/**
* 验证:收集流中的结果到集合中
**/
@Test
public void testCollectStreamToList(){
Stream<String> stream = Stream.of("a", "b", "c");
List<String> list = stream.collect(Collectors.toList());
Stream<String> stream2 = Stream.of("a", "a", "c");
Set<String> set = stream2.collect(Collectors.toSet());
System.out.println(list);
System.out.println(set);
}
/**
* 验证:收集流中的结果到数组中
**/
@Test
public void testCollectStreamToArr(){
//简写方式
Stream<String> stream = Stream.of("a","b");
String[] strings = stream.toArray(String[]::new);
for (String string : strings) {
System.out.println(string);
}
//常规写法
Stream<String> stringStream = Stream.of("a","b");
String[] strArr = stringStream.toArray((int i) -> {
return new String[i];
});
for (String s : strArr) {
System.out.println(s);
}
}
/**
* 验证:对流中数据进行聚合计算
* 聚合:对一组值执行计算并返回单一的值
**/
@Test
public void testAggregateStream(){
Stream<Person> pStream = Stream.of(
new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 77)
);
//获取分数最大值
/*Optional<Person> max = pStream.collect(Collectors.maxBy((Person p1,Person p2)->{return p1.score - p2.score;}));
System.out.println(max.get().getScore());*/
//获取分数最小值
/*Optional<Person> min = pStream.collect(Collectors.minBy((Person p1,Person p2)->{return p1.score - p2.score;}));
System.out.println(min.get().getScore());*/
//求总和
/*Integer collect = pStream.collect(Collectors.summingInt(new ToIntFunction<Person>() {
@Override
public int applyAsInt(Person value) {
return value.score;
}
}));
System.out.println(collect);*/
//平均值
/*Double collect = pStream.collect(Collectors.averagingInt((Person p)->{return p.getScore();}));
System.out.println(collect);*/
//统计数量
Long collect = pStream.collect(Collectors.counting());
System.out.println(collect);
}
/**
* 验证:对流中数据进行单极分组
**/
@Test
public void testStreamSingleGroup(){
Stream<Person> pStream = Stream.of(
new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 7)
);
//按年龄分组
/*Map<Integer, List<Person>> collect = pStream.collect(Collectors.groupingBy(new Function<Person, Integer>() {
@Override
public Integer apply(Person person) {
return person.getAge();
}
}));
collect.forEach(new BiConsumer<Integer, List<Person>>() {
@Override
public void accept(Integer integer, List<Person> people) {
System.out.println(integer);
System.out.println(people);
}
});*/
//按分数是否>60分组
Map<String, List<Person>> collect = pStream.collect(Collectors.groupingBy(person -> {
if (person.getScore() >= 60) {
return "Y";
}
return "N";
}));
collect.forEach((s, people) -> {
System.out.println(s);
System.out.println(people);
});
}
/**
* 验证:对流中数据进行多级分组
**/
@Test
public void testStreamMultiGroup(){
Stream<Person> pStream = Stream.of(
new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 7)
);
//先按年龄分组,再按成绩分组
Map<Integer, Map<String, List<Person>>> collect = pStream.collect(Collectors.groupingBy(
(Person p) -> {
return p.getAge();
},
Collectors.groupingBy((Person p) -> {
if (p.getScore() > 90)
return "A";
return "B";
})
));
collect.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
}
/**
* 验证:List转Map
**/
@Test
public void testStreamListToMap(){
ArrayList<Person> pList = CollectionUtil.newArrayList(
new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 7)
);
Stream<Person> pStream = pList.stream();
Map<String, Person> collect = pStream.collect(Collectors.toMap(Person::getName, p -> p,(k1,k2)->k1));
collect.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
}
/**
* 验证:对流中数据进行分区
* 固定以true : false 进行分组
**/
@Test
public void testStreamPartition(){
Stream<Person> pStream = Stream.of(new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 7));
/*Map<Boolean, List<Person>> collect = pStream.collect(Collectors.partitioningBy((Person p) -> {
if (p.score > 90)
return true;
return false;
}));*/
Map<Boolean, Map<Integer, List<Person>>> collect = pStream.collect(Collectors.partitioningBy(
(Person p) -> {
if (p.score > 90)
return true;
return false;
},
Collectors.groupingBy(Person::getAge)
));
collect.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
});
}
/**
* 验证:对流中数据进行拼接
**/
@Test
public void testStreamJoin(){
Stream<Person> pStream = Stream.of(new Person("赵丽颖", 58, 95),
new Person("杨颖", 56, 88),
new Person("迪丽热巴", 56, 99),
new Person("柳岩", 52, 7));
String collect = pStream.map(Person::getName).collect(Collectors.joining("::", "S", "E"));
System.out.println(collect);
}
/**
* 验证:并行流的获取和使用
**/
@Test
public void testParallelStream(){
ArrayList<String> strings = CollectionUtil.newArrayList("1", "2", "d", "5", "ef");
//获取
Stream<String> parallel = strings.stream().parallel();
Stream<String> stringStream = strings.parallelStream();
//使用
parallel.forEach(s->{
System.out.println(Thread.currentThread() + "," + s);
});
}
/**
* 验证:三种方式进行累加操作的效率对比
**/
@Test
public void testStreamSumEfficient(){
long times = 500000000L;
long startTime = 0L;
//for循环
startTime = getStartTime();
long result = 0L;
for (int i = 0; i <= times; i++) {
result += i;
}
System.out.println("for循环"+ result +"耗时:" + calcConsumingTime(startTime));
//普通流
startTime = getStartTime();
LongStream.rangeClosed(0,times).sum();
System.out.println("普通Stream"+ result +"耗时:" + calcConsumingTime(startTime));
//并行流
startTime = getStartTime();
LongStream.rangeClosed(0,times).parallel().sum();
System.out.println("并行Stream"+ result +"耗时:" + calcConsumingTime(startTime));
}
/**
* 验证:并行流的线程安全问题
**/
@Test
public void testParallelStreamThreadSafe(){
ArrayList<Long> lists = CollectionUtil.newArrayList();
LongStream.rangeClosed(0,1000).parallel().forEach(s->{
lists.add(s);
});
System.out.println(CollectionUtil.size(lists));
}
/**
* 验证:fork/join
**/
@Test
public void testForkJoin(){
ForkJoinPool pool = new ForkJoinPool();
SumRecursiveTask<Long> task = new SumRecursiveTask<>(1, 10000L);
Long result = pool.invoke(task);
System.out.println("最终结果="+result);
}
/**
* 验证:Optional用法
**/
@Test
public void testOptional(){
//创建实例:放入non-null的值
Optional<String> name = Optional.of("a");
//创建实例:放入null,则返回空实例
Optional.ofNullable(null);
//创建实例: 等同于放入null
Optional.empty();
//判断是否存在值,存在则执行操作
if (Optional.ofNullable("aa").isPresent()){
//System.out.println(name.get());
}
//判断是否存在值,存在则执行操作
Optional.of("aa").ifPresent((String s)-> System.out.println(s));
//获取值,没有则报错
System.out.println(name.get());
//获取值,没有则返回orElse中的内容
Optional.ofNullable(null).orElse("空字符串");
///获取值,没有则返回orElseGet中的内容
Optional.ofNullable(null).orElseGet(()-> "a");
//处理值,没有则返回Optional.empty(),传返回的Optional类型必须与原始Optional一致
Optional<String> aa = Optional.ofNullable("aa").map((String s) -> {
return 1+"";
});
//处理值,没有则返回Optional.empty(),返回的Optional类型由自己定义
Optional<Integer> aa1 = Optional.ofNullable("aa").flatMap(new Function<String, Optional<Integer>>() {
@Override
public Optional<Integer> apply(String s) {
return Optional.of(1);
}
});
//综合案例
Optional.ofNullable(new Person("张三", 16, 98)).flatMap((new Function<Person, Optional<String>>() {
@Override
public Optional<String> apply(Person person) {
return Optional.ofNullable(person.getName().concat("aaa"));
}
})).ifPresent(System.out::println);
}
/**
* 计算总和的任务类
*/
class SumRecursiveTask<L extends Number> extends RecursiveTask<Long>{
private static final long THRESHOLD = 3000l;
private final long start;
private final long end;
SumRecursiveTask(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end - start;
//小于阈值,计算总和
if (length <= THRESHOLD){
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
System.out.println("计算"+ start +"->"+ end +",结果为" + sum);
return sum;
}else {
//否则继续拆分
long middle = (start + end)/2;
RecursiveTask<Long> left = new SumRecursiveTask<Long>(start, middle);
left.fork();
RecursiveTask<Long> right = new SumRecursiveTask<Long>(middle+1, end);
right.fork();
return left.join() + right.join();
}
}
}
public static Long getStartTime(){
return System.currentTimeMillis();
}
public static Long calcConsumingTime(Long startTime){
return (System.currentTimeMillis()) - startTime;
}
@Data
@AllArgsConstructor
class Person{
private String name;
private int age;
private int score;
public Person(){}
public Person(String name){
this.name = name;
}
public Person(String name,int age){
this.name = name;
this.age = age;
}
}
}
本文来自博客园,作者:江南西道,转载请注明原文链接:https://www.cnblogs.com/jiangnanxidao/p/15639852.html