lombda表达式,又称语法糖,作用在于简化开发,将匿名内部类(语法糖,不具有改变原变量的能力,)
lombda表达式的特性:在不使用的情况不会加载,一直处于懒加载状态
public class demo21 {
public static void main(String[] args) {
List<person> list = new ArrayList<>();
list.add(new person("张三",18,"4000"));
list.add(new person("李四",20,"5000"));
list.add(new person("王五",22,"6000"));
list.add(new person("刘七",26,"7000"));
Collections.sort(list, new Comparator<person>() {
@Override
public int compare(person o1, person o2) {
// o1.getAge();
return Integer.compare(o1.getAge(),o2.getAge());
}
}); //简化前
Collections.sort(list,(x,y)->Integer.compare(x.getAge(),y.getAge()));//简化后
}
}
java8为lombda添加了4大内置函数,囊括了所有业务场景
Consumer<T> //消费性 有参数,无返回值
accept(T t)
Supplier<T> //供给型 无参数,有返回值
T get()
Function(T,R) //函数型 有参数,有返回值
T apply(R r)
Predicate(T) //断言型 有参数,返回boolean值
boolean test(T t)
具有代表性的接口
Collections.sort((x)->{});
Comparator<Integer> com = ((x,y)->{return Integer.compare(x,y);});
/**
* 方法引用
* 在lombda 体中的内容有方法已经实现了
*
* 对象::实例方法名
* 类::静态方法名
* 类::实例方法名
*
* 构造器引用
* ClassName::new
*
* 数组引用
* Type::new
*/
public class Demo1 {
public static void main(String[] args) {
PrintStream ps = System.out;
Consumer<String> consumer1 = (x)-> ps.println(x);
Consumer<String> consumer = ps::println; //对象::实例方法名
Consumer<String> consumer2 = System.out::println;
User user = new User();
Supplier<Integer> supplier1 = ()-> user.getAge();
Supplier<String> supplier = user::getName; //对象::实例方法名
Comparator<Integer> comparator = Integer::compareTo; //类::静态方法名
System.out.println(comparator.compare(1, 2)); //要注意返回值类型要保持一致
//断言型函数的实现类 可以有多个参数
BiPredicate<String,String> biPredicate = (x,y) -> x.equals(y);
BiPredicate<String,String> biPredicate1 = String::equals; //类::实例方法名
Supplier<User> supplier2 = User::new; //构造器引用
User user1 = supplier2.get();
Function<String,User> function = User::new;
//函数式接口实现类 如果需要更多的参数,可以参考源码中的方式 apply套apply
BiFunction<String,Integer,User> function1 = User::new;
Function<Integer,String[]> function2 = String[]::new; //数组引用 这个基本不会用到
}
}
/**
* stream 不会存储元素
* 不会改变源对象,会生成一个新的流
* 延迟操作,只有在需要结果的时候才会执行
*
* 俩种创建流的方式
* stream() parallelStream() Stream.of()
*/
public class StreamDemo {
public static void main(String[] args) {
List<User> list = new ArrayList<>();
list.add(new User("张三", 12, 5000.00));
list.add(new User("王五", 3, 6000.00));
list.add(new User("赵六", 14, 7000.00));
list.add(new User("刘八", 15, 8000.00));
list.add(new User("唐玖", 16, 9000.00));
/**
* 开始操作,将集合转换为流
*/
list.stream(); //串行流 类似单线程
list.parallelStream();//并行流 类似多线程
Stream.of(list);
/**
* 中间操作
* 筛选与切片
* filter 接收一个lambda predicate
* limit 截断
* skip(n) 跳过n元素
* distinct 筛选,通过流锁生成的元素的hashcode()和equals()去除重复元素
*/
list.stream().filter(x -> x.getAge()>10)
.limit(2)
.skip(1)
.distinct()
.forEach(System.out::println);
/**
* 中间操作
* 映射
* map 将流中的每一个元素都应用在函数上
* flatMap
*/
list.stream().map(User::getName)
.collect(Collectors.toList())
.forEach(System.out::println);
/**
* 中间操作
* 排序
* sort() 自然排序
* sort(Comparable) 自定义排序
*/
list.stream().sorted().collect(Collectors.toList());
list.stream().sorted((x,y) -> {
if(x.getAge().equals(y.getAge())){
return x.getName().compareTo(y.getName());
}else {
return x.getName().compareTo(y.getName());
}
}).collect(Collectors.toList());
/**
* 结束操作
* 查找与匹配
* allMatch 检查是否匹配所有元素
* anyMatch 检查是否满足至少一个元素匹配
* noneMatch 检查是否没有元素匹配
* findFirst 返回第一个元素
* findAny 返回当前流中的任意元素
* count 返回流中元素的总个数
* max 返回流中的最大元素
* min 返回流中的最小元素
*
*
* Optional容器类,避免空指针异常
* 通过get()方法返回对象
*/
boolean 张三 = list.stream().allMatch(x -> x.getName().equals("张三"));
boolean 张三1 = list.stream().anyMatch(x -> x.getName().equals("张三"));
boolean 张三2 = list.stream().noneMatch(x -> x.getName().equals("张三"));
Optional<User> first = list.stream().findFirst();
User user2 = first.get();
Optional<User> any = list.stream().findAny();
User user3 = any.get();
long count = list.stream().count();
Optional<User> max = list.stream().max((x, y) -> x.getAge().compareTo(y.getAge()));
User user = max.get();
Optional<User> min = list.stream().min((x, y) -> x.getAge().compareTo(y.getAge()));
User user1 = min.get();
/**
* 规约
* reduce 将流中元素反复结合起来,得到一个值(通常配合map使用)
*/
Optional<Double> reduce = list.stream().map(x -> x.getSalary())
.reduce(Double::sum);
/**
* 收集
* collection 将流转换为其他形式
*
* Collectors 很强大的工具类
*/
List<User> collect = list.stream().collect(Collectors.toList());
}
}
/**
* 并行流与串行流
*
* 在流的基础上
* .parallel 切换并行流
* .sequential() 切换串行流
*
* 并行流的底层是ForkJoin框架
* ForkJoin框架的核心概念是将一个大任务拆分成若干个小任务
* 将所有小任务压缩进cpu线程当中
* 当其中一个小任务完成后,会从别的线程中末尾获取任务,继续执行,直到所有任务完成
*/
//ForkJoin demo
import java.util.concurrent.RecursiveTask;
public class ForkJoinDemo extends RecursiveTask<Long> { //继承该类是有返回值,RecursiveAction没有返回值
private long start;
private long end;
private static final long THRESHOLD = 10000;
public ForkJoinDemo(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;
}
return sum;
}else {
long mid = (start + end)/2;
ForkJoinDemo left = new ForkJoinDemo(start,mid);
left.fork();
ForkJoinDemo right = new ForkJoinDemo(mid+1,end);
right.fork();
return left.join() + right.join();
}
}
}
public static void main(String[] args) {
/**
* java7 的做法
*/
Instant start = Instant.now(); //java8的时间
ForkJoinPool forkJoinPool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinDemo(0,1000000L);
Long invoke = forkJoinPool.invoke(task);
System.out.println(invoke);
Instant end = Instant.now();
System.out.println(Duration.between(start,end).toMillis()); //时差
/**
* java8 进行改进
*/
LongStream.rangeClosed(0,1000000000L)
.parallel() //底层是ForkJoin
.reduce(0,Long::sum);
}
/**
* 容器类
* java8避免空指针异常的容器类
* 个人理解有点像三目运算法 不为null直接返回,为null给另外一个值
*/
public class OptionalDemo {
public static void main(String[] args) {
Optional<User> user = Optional.of(new User());
System.out.println(user.get());
Optional<User> empty = Optional.empty();
if(empty.isPresent()){
System.out.println(empty.get());
}
User user2 = empty.orElseGet(() -> new User());
User user3 = empty.orElse(new User("张三", 1, 12.2));
Optional<User> user1 = Optional.ofNullable(new User());
Optional<String> s2 = user1.flatMap((x) -> Optional.of(x.getName()));
String s3 = s2.get();
Optional<String> s = user1.map((x) -> x.getName());
String s1 = s.get();
System.out.println(user1.get());
}
}
java7与java8对于时间线程安全的处理方式区别
java7
public class NewDateDemo {
/**
* java7在多线程中格式化时间
* 解决线程安全的方式
*
*/
public static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>(){ //给对象加锁
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyyMMdd");
}
};
public static Date convert(String source) throws Exception{ //给时间格式化
return df.get().parse(source);
}
public static void main(String[] args) throws Exception{
Callable<Date> callable = new Callable<Date>() { //创建线程
@Override
public Date call() throws Exception {
return NewDateDemo.convert("20220321");
}
};
ExecutorService pool = Executors.newFixedThreadPool(10); //创建线程池
List<Future<Date>> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
result.add(pool.submit(callable));
}
for (Future<Date> future : result) {
System.out.println(future.get());
}
pool.shutdown(); //关闭线程池
}
}
java8
public class NewDateDemo1 {
public static void main(String[] args) throws Exception{
/**
* java8对于时间格式化的安全线程处理
*/
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");//java8 不需要使用锁去锁对象
Callable<LocalDate> callable = new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
return LocalDate.parse("20220211",dateTimeFormatter);
}
};
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
result.add(executorService.submit(callable));
}
for (Future<LocalDate> localDateFuture : result) {
System.out.println(localDateFuture.get());
}
}
}
/**
* LocalDateTime
* LocalDate
* LocalTime
* Instant 时间戳(从unix元年1970年1月1日 00:00:00 到当前时间的毫秒值)
*
* Duration
* Period
*/
public class JavaTimeDemo {
public static void main(String[] args) {
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
LocalDateTime of = LocalDateTime.of(2022, 10, 13, 19, 22, 33);
System.out.println(of);
System.out.println(localDateTime.plusWeeks(10));//年,月,日,十,分,秒 加法运算 不管怎么运算都会生成一个新的实例
System.out.println(localDateTime.minusDays(10));//减法运算
System.out.println(localDateTime.getMonth()); //获取月
LocalDate localDate = LocalDate.now();
System.out.println(localDate);
LocalTime localTime = LocalTime.now();
System.out.println(localTime);
Instant instant = Instant.now(); //默认获取UTC时区 世界协调时间
System.out.println(instant);
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8)); //相差8个时区就是中国时间
System.out.println(offsetDateTime);
System.out.println(instant.toEpochMilli()); //转成毫秒值
Instant instant1 = Instant.ofEpochMilli(10000); //毫秒值转为时间格式
//计算俩个时间戳的间隔,因为参数是Temporal接口,所以实现了Temporal的实现类都可以作为参数传递
System.out.println(Duration.between(LocalDateTime.now(), LocalDateTime.now().plusWeeks(1)).toMillis());
//计算俩个时期的间隔,参数为LocalDate
System.out.println(Period.between(LocalDate.now(), LocalDate.now().plusWeeks(1)).getDays());
}
}
/**
* DateTimeFormatter 日期格式化
*/
@Test
public void test(){
DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_DATE_TIME; //api提供日期格式化
LocalDateTime now = LocalDateTime.now();
String format = now.format(isoDateTime);
System.out.println(format);
/**
* 转换过程中注意格式
*/
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");//自定义格式化
String format1 = dateTimeFormatter.format(now); //将LocalDateTime转换为字符串
System.out.println(format1);
LocalDateTime parse = now.parse(format1, dateTimeFormatter); //将字符串转换为LocalDateTime
System.out.println(parse);
}
java8新特性完结