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());
		}
		
	}
}
posted @ 2021-08-13 21:02  CN_Darren  阅读(39)  评论(0)    收藏  举报