Day33-java8新特性
注解
代码里的特殊标记,给程序看的
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 注解 【注意事项】
* 1、使用@interface定义注解 2、注解中只包含属性
* 3、注解中属性类型只能是字符串类型,基本数据类型,class数据类型,枚举类型,注解类型以及他们的一维数组
* 4、属性可以赋初始值 5、元注解
* 6、有些注解只能放在方法上 7、如果注解中只有一个属性,属性名为value,赋值时可以不写value
*/
//注解上加注解使它变成运行状态 运行时存活
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = { ElementType.METHOD }) // 数组用花括号{}
public @interface MyAnnotation {
// 利用default给属性赋初始值 没有赋值的在使用注解时要赋值
// String name()default "张三";
String name();
int age() default 18;
// Class<?> class1();
// Gender gender();
// MyAnnotation2 annotation2();
}
public @interface MyAnnotation2 {
String value();
}
import java.lang.reflect.Method;
//注解只能放在方法上
//@MyAnnotation2(name = "张三")
public class Person {
@MyAnnotation(name = "张三",age=16)
@MyAnnotation2("aa")
public void show() throws Exception {
//使用注解
//获取类对象
Class<?> class1 = Person.class;
//获取show方法
Method method = class1.getMethod("show");
//获取注解 通过类对象
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
System.out.println(annotation.name()+"--->"+annotation.age());
}
}
public class TestPerson {
public static void main(String[] args) throws Exception {
Person person = new Person();
person.show();
}
}
java8新特性
Lambda表达式
使用Lambda表达式使得语法更加简洁。基本结构为() -> {}
没有参数,就用一个()表示;
有参数的话,就将参数写在()里面;
函数体中只有一条语句时,{}可以省略
import java.util.Comparator;
public class TestLambda {
public static void main(String[] args) {
//案例一 匿名内部类每次生成class文件 Lambda表达式不会
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
};
new Thread(runnable).start();
//使用Lambda表达式
//把new 类头和尾删了 声明删了 加箭头
Runnable runnable2 = () -> {
System.out.println(Thread.currentThread().getName());
};
//使用Lambda表达式
//只有一句话,无返回值,可以把{}也省了
Runnable runnable3 = () -> System.out.println(Thread.currentThread().getName());
//案例二:
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
};
//使用Lambda表达式
Comparator<Integer> comparator2 = (Integer o1, Integer o2) -> {
return o1 - o2;
};
//使用Lambda表达式 有一条语句,省去{}
Comparator<Integer> comparator3 = (Integer o1, Integer o2) -> o1 - o2;
}
}
当然,这种方式虽使得代码更加简洁了,但其可读性相对也变差了。
函数式接口FunctionalInterface
我们把只定义了单方法的接口称之为函数式接口,用注解@FunctionalInterface标记
@FunctionalInterface
public interface USB {
void service();
}
函数式接口可以使用Lambda表达式
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
/**
* 函数式接口
* 【消费型接口】Consumer<T> 有参无返回值 void accept(T t);对类型为T的对象应用操作 【输出打印】
* 【供给型接口】Supplier<T> 无参有返回值 T get();返回类型为T的对象 【需要什么返回什么】
* 【函数型接口】Function<T,R> 有参有返回值 R apply(T t); 【得到数据 返回】
* 【断言型接口】Predicate<T> 有参有返回值 boolean test(T t); 【判断,符合要求的不符合要求的】
*/
public class TestFunctionalInterface {
public static void main(String[] args) {
System.out.println("=============【消费型接口】=============");
// Consumer<Double> consumer = new Consumer<Double>() {
//
// @Override
// public void accept(Double t) {
// System.out.println("大家一起聚餐,花费了:"+t);
// }
// };
//Lambda表达式
Consumer<Double> consumer = t -> System.out.println("大家一起聚餐,花费了:" + t);
happy(consumer, 1000);
System.out.println("=============【供给型接口】=============");
// Supplier<Integer> supplier = new Supplier<Integer>() {
//
// @Override
// public Integer get() {
// //返回随机数
// return new Random().nextInt(100);
// }
// };
//Lambda表达式
Supplier<Integer> supplier = () ->new Random().nextInt(100);
//返回数组
int[] nums = getNums(supplier, 5);
System.out.println(Arrays.toString(nums));
System.out.println("=============【函数型接口】=============");
String str = handler(s->s.toUpperCase(), "hello");
System.out.println(str);
String str2 = handler(s->s.trim()," Hello ");
System.out.println(str2);
System.out.println("=============【断言型接口】=============");
ArrayList<String> list = new ArrayList<String>();
list.add("zhangsan");
list.add("lisi");
list.add("wangwu");
list.add("zhangliu");
// Predicate<String> predicate = new Predicate<String>() {
//
// @Override
// public boolean test(String t) {
// if (t.startsWith("zhang")) {
// return true;
// }
// return false;
// }
// };
//Lambda表达式简化
Predicate<String> predicate = t -> {
if (t.startsWith("zhang")) {
return true;
}
return false;
};
List<String> list2 = filter(predicate, list);
System.out.println(list2);
}
//消费型接口
public static void happy(Consumer<Double> consumer,double money) {
consumer.accept(money);
}
//供给型接口 返回数组
public static int[] getNums(Supplier<Integer> supplier,int count) {
//数组长度
int[] nums = new int[count];
//遍历
for (int i = 0; i < count; i++) {
//将得到的放进数组
nums[i] = supplier.get();
}
return nums;
}
//函数型接口
public static String handler(Function<String, String>function,String s) {
return function.apply(s);
}
//断言型接口 相当于过滤
public static List<String> filter(Predicate<String>predicate,List<String>list) {
//集合 适合存储数据
ArrayList<String> newList = new ArrayList<String>();
for (String string : list) {
if (predicate.test(string)) {
newList.add(string);
}
}
return newList;
}
}
方法引用
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
import java.io.PrintStream;
import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* 方法引用
* 是对Lambda表达式的一种简写形式,如果Lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
* 常见形式:
* 对象::实例方法
* 类::静态方法
* 类::实例方法
* 类::new
*/
public class TestMethod {
public static void main(String[] args) {
// 对象::实例方法
// Consumer<String> consumer = t->System.out.println(t);
// consumer.accept("hello");
// PrintStream ps = System.out;
// ps.println("hello");
// 对象::实例方法
Consumer<String> consumer = System.out::println;
consumer.accept("hello");
// 类::静态方法
// Comparator<Integer> comparator =(o1,o2)->Integer.compare(o1, o2);
Comparator<Integer> comparator =Integer::compare;
// 类::实例方法
// Comparator<String> comparator2 =(o1,o2)->o1.compareTo(p2)
Comparator<String> comparator2 =String::compareTo;
// 类::new
// Supplier<Student> supplier = ()->new Student();
Supplier<Student> supplier = Student::new;
System.out.println(supplier.get().toString());
//元素类型[]::new
// Function<Integer, String[]> function = t->new String[t];
Function<Integer, String[]> function = String[]::new;
}
}
StreamAPI
不是流,和流的功能差不多,与集合类似,Stream中保存对集合或数组的操作
Stream的创建
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class TestStream1 {
public static void main(String[] args) {
//创建流
//1、通过集合方法
System.out.println("===============1、通过集合方法===============");
ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "zhangsan","lisi","wangwu","wangliu");
System.out.println("元素个数:"+list.size());
//先变成流
Stream<String> stream = list.stream();
//中间操作 过滤 forEach结束
stream.filter(s->s.startsWith("wang")).forEach(System.out::println);
//2、通过Arrays类中的stream()方法
System.out.println("===============2、通过Arrays类中的stream()方法===============");
//new一个数组,返回int类型数组
IntStream stream2 = Arrays.stream(new int[] {10,8,2,60});
//计数
System.out.println(stream2.count());
//3、通过Stream接口的of(),iterate(),generate()方法
System.out.println("===============3、通过Stream接口的of(),iterate(),generate()方法===============");
//of()
System.out.println("==============================");
Stream<Integer> stream3 = Stream.of(20,17,65,85,34);
stream3.forEach(System.out::println);
//iterate()
System.out.println("==============================");
Stream<Integer> stream4 = Stream.iterate(1, x->x+2);
stream4.limit(10).forEach(System.out::println);
//generate()
System.out.println("==============================");
Stream<Integer> stream5 = Stream.generate(()->new Random().nextInt(100));
stream5.limit(4).forEach(System.out::println);
//4、通过range(), rangeClosed()
System.out.println("===============4、通过range(), rangeClosed()===============");
IntStream.range(0, 10).forEach(System.out::println);
System.out.println("==============================");
//rangeClosed和range区别是包含最后一个元素
IntStream.rangeClosed(0, 10).forEach(System.out::println);
}
}
中间操作
import java.util.Objects;
public class Student {
private String name;
private int age;
private double score;
public Student() {
}
/**
* @param name
* @param age
* @param score
*/
public Student(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
@Override
public int hashCode() {
return Objects.hash(age, name, score);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
return age == other.age && Objects.equals(name, other.name)
&& Double.doubleToLongBits(score) == Double.doubleToLongBits(other.score);
}
}
import java.util.ArrayList;
import java.util.stream.Stream;
/**
* 中间操作
* filter(过滤),limit(限制),skip(跳过),distinct(去重),sorted(排序)
* map映射
* parallel
* distinct(去重)重写equals方法,因为List中允许存在重复元素
*/
public class TestStream2 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",18,98.5));
list.add(new Student("lisi",16,100));
list.add(new Student("wangwu",17,99));
list.add(new Student("wangliu",16,96));
list.add(new Student("zhangsan",18,98.5));//重复元素
System.out.println("元素个数:"+list.size());
//filter(过滤),limit(限制),skip(跳过),distinct(去重),sorted(排序)
//filter(过滤)
//获取年龄大于17的学生对象
//先把它变成流
Stream<Student> stream =list.stream();
stream.filter(s->s.getAge()>=17).forEach(System.out::println);
//终止后流就用不了了
//limit(限制)
Stream<Student> stream2 = list.stream();
stream2.limit(3).forEach(System.out::println);
//skip(跳过)
Stream<Student> stream3 = list.stream();
stream3.skip(2).forEach(System.out::println);
//distinct(去重)
System.out.println("============");
Stream<Student> stream4 = list.stream();
//重写equals方法,因为List中允许存在重复元素
stream4.distinct().forEach(System.out::println);
//sort(排序)
System.out.println("============");
Stream<Student> stream5 = list.stream();
//排序 默认升序
stream5.sorted((o1,o2)->Double.compare(o1.getScore(), o2.getScore())).forEach(System.out::println);
//map (映射)
System.out.println("============");
Stream<Student> stream6 = list.stream();
stream6.map(s->s.getName()).forEach(System.out::println);
//parallel (并行流)
System.out.println("============");
Stream<Student> stream7 = list.stream();
stream7.parallel().forEach(System.out::println);
}
}
终止操作
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* 终止操作
* reduce collect
*/
public class TestStream3 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",18,98.5));
list.add(new Student("lisi",16,100));
list.add(new Student("wangwu",17,99));
list.add(new Student("wangliu",16,96));
list.add(new Student("zhangsan",18,98.5));//重复元素
System.out.println("元素个数:"+list.size());
//forEach
//min 返回最小值对象
Optional<Student> min = list.stream().min((o1,o2)->Integer.compare(o1.getAge(), o2.getAge()));
Student student = min.get();
System.out.println("年龄最小的是:"+student.getName());
//max 返回最大值对象
//count
//reduce 统计
//求成绩和
Optional<Double> sum = list.stream().map(s->s.getScore()).reduce((d1,d2)->d1+d2);
System.out.println(sum.get());
//平均分
System.out.println(sum.get()/list.size());//list.count()个数也行
//collect 收集
//获取所有成绩集合
List<Double> collect = list.stream().map(s->s.getScore()).collect(Collectors.toList());
for (Double double1 : collect) {
System.out.println(double1);
}
}
}
其他操作
import java.util.ArrayList;
import java.util.stream.Stream;
/**
* 演示延迟操作
*/
public class TestStream4 {
public static void main(String[] args) {
ArrayList<Student> list = new ArrayList<Student>();
list.add(new Student("zhangsan",18,98.5));
list.add(new Student("lisi",16,100));
list.add(new Student("wangwu",17,99));
list.add(new Student("wangliu",16,96));
list.add(new Student("zhangsan",18,98.5));//重复元素
System.out.println("元素个数:"+list.size());
//中间操作延迟,等待终止操作
Stream<Student> stream = list.stream();
stream.filter(s->{
System.out.println("过滤了");
return s.getScore() > 90;
}).count();//调用终止方法才停止
}
}
import java.util.ArrayList;
import java.util.UUID;
/**
* 通过Collection集合的stream()或parallelStream()方法
*/
public class TestStream5 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 500000; i++) {
//随机获取UUID
list.add(UUID.randomUUID().toString());
}
System.out.println("元素个数:"+list.size());
//测试时间差 看效率
long start = System.currentTimeMillis();
// long count = list.stream().sorted().count();
long count = list.parallelStream().sorted().count();
System.out.println("总个数"+count);
long end = System.currentTimeMillis();
System.out.println("时间差:"+(end - start));
}
}
新时间API
之前的时间API存在问题:线程安全问题,设计混乱
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
//线程不安全,多运行几遍,切换CPU,数字格式化问题,加同步锁
public class TestSimpleDateFormat {
public static void main(String[] args) throws Exception{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//线程池
ExecutorService es = Executors.newFixedThreadPool(5);
ArrayList<Future<Date>> list = new ArrayList<Future<Date>>();
for (int i = 0; i < 5; i++) {
//Callable有返回类型
Future<Date> future = es.submit(new Callable<Date>() {
@Override
public Date call() throws Exception {
// 加同步
synchronized (this) {
return sdf.parse("2021-08-13");
}
}
});
list.add(future);
}
for (Future<Date> future : list) {
System.out.println(future.get());
}
}
}
本地化时间API:
LocalDate
LocalTime
LocalDateTime:类似Calender
import java.time.LocalDateTime;
/**
* 本地化日期时间API
*
*/
public class TestLocal {
public static void main(String[] args) {
//创建本地日期时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.getYear());
System.out.println(localDateTime.getMonth());//英文月份
System.out.println(localDateTime.getMonthValue());//数字月份
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getHour());
System.out.println(localDateTime.getMinute());
System.out.println(localDateTime.getSecond());
//昨天
System.out.println("======================");
LocalDateTime yesterday = localDateTime.minusDays(1);
System.out.println(yesterday.getDayOfMonth());
//明天
System.out.println("======================");
LocalDateTime tomorrow = localDateTime.plusDays(1);
System.out.println(tomorrow.getDayOfMonth());
}
}
Instant:时间戳
import java.time.LocalDateTime;
/**
* 本地化日期时间API
*
*/
public class TestLocal {
public static void main(String[] args) {
//创建本地日期时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.getYear());
System.out.println(localDateTime.getMonth());//英文月份
System.out.println(localDateTime.getMonthValue());//数字月份
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getHour());
System.out.println(localDateTime.getMinute());
System.out.println(localDateTime.getSecond());
//昨天
System.out.println("======================");
LocalDateTime yesterday = localDateTime.minusDays(1);
System.out.println(yesterday.getDayOfMonth());
//明天
System.out.println("======================");
LocalDateTime tomorrow = localDateTime.plusDays(1);
System.out.println(tomorrow.getDayOfMonth());
}
}
ZonID:时区
import java.time.ZoneId;
import java.util.Set;
/**
* ZoneId时区
*/
public class TestZoneId {
public static void main(String[] args) {
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
//获取所有时区
for (String string : availableZoneIds) {
System.out.println(string);
}
System.out.println("===========");
//获取当前时区
ZoneId systemDefault = ZoneId.systemDefault();
System.out.println(systemDefault);
}
}
Date、Instant、LocalDateTime的转换
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
/**
* Date、Instant、LocalDateTime的转换
*/
public class Test {
public static void main(String[] args) {
//Date->Instant->LocalDateTime
Date date = new Date();
//变成时间戳
Instant instant = date.toInstant();
//变成本地时间
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
//LocalDateTime->Instant->Date
Instant instant2 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date date2 = Date.from(instant2);
System.out.println(date2);
}
}
DateTimeFormatter:格式化类
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* DateTimeFormatter格式化类 如何用?把所有SimpleDateFormat换成DateTimeFormatter
*/
public class TestDateTimeFormatter {
public static void main(String[] args) throws Exception{
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//线程池
ExecutorService es = Executors.newFixedThreadPool(5);
ArrayList<Future<LocalDate>> list = new ArrayList<Future<LocalDate>>();
for (int i = 0; i < 5; i++) {
//Callable有返回类型
Future<LocalDate> future = es.submit(new Callable<LocalDate>() {
@Override
public LocalDate call() throws Exception {
// 加同步
synchronized (this) {
return LocalDate.parse("2021-08-13",dtf);
}
}
});
list.add(future);
}
for (Future<LocalDate> future : list) {
System.out.println(future.get());
}
}
}

浙公网安备 33010602011771号