并行流与串行流、Optional、接口的默认方法与静态方法、日期组件、重复注解

Day28

并行流与串行流

并行流就是把一个内容拆分成多个数据块,并用不同的线程分别处理每个数据块的流。Java8中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API可以声明性地通过 parallel() - 并行流 与sequential()-顺序流 之间进行切换。

注意

  1. 默认为顺序流/串行流
  2. 并行流一般在大数据搜索里使用到
  3. JDK1.8之前也有并行流,叫做Fork/Join并行计算框架

Optional

Optional类(java. util. Optional)是一个容器类,代表一个存在或不存在的值,原来用null表示一个值不存在,现在Optional可以更好的表达这个概念。并且可以避免空指针异常

此类的设计就是更好的避免空指针异常

方法描述
Optional.of(T t)创建一个Optional实例
Optional.empty()创建一 个空的 Optional实例
Optional.ofNullable(T t)若t不为null,创建Optional实例,否则创建空实例
get()获取Optional实例里的对象
isPresent()判断是否包含值
orElse(T t)如果调用对象包含值, 返回该值,否则返回t
orElseGet(Supplier s)如果调用对象包含值,返回该值,否则返回s获取的值
map(Function f)如果有值对其处理,并返回处理后的Optional,否则返回optional. empty()
flatMap(Function mapper)与map 类似,要求返回值必须是Optional
public class Test1 {
	@Test
	public void test01() {
		//创建一个Optional实例,把对象封装到Optional容器里
//		Optional<Student> op = Optional.of(
//          new Student("aaa", 26, 6666, Course.HTML));
        
		//创建一个空的Optional容器
//		Optional<Student> op = Optional.empty();
		
        //创建一个Optional实例,若对象为null->创建空实例,若对象为不为null->创建Optional实例
		Optional<Student> op = Optional.ofNullable(
            new Student("bbb", 26, 7777, Course.PYTHON));
		
		//判断容器里是否包含对象
		if(op.isPresent()){//包含
			System.out.println("获取容器里的对象:" + op.get().getName());
		}else{//不包含
			System.out.println("容器里的对象为null");
		}
		
		//如果容器里有对象就返回,否则就返回新对象
		Student stu = op.orElse(new Student("ccc", 26, 8888, Course.JAVA));
		System.out.println(stu.getName());
		
		//不同情况下可以返回不同对象,orElseGet()比orElse()可变性更强
		boolean bool = true;
		stu = op.orElseGet(()->{
			if(bool){
				return new Student("吴彦祖", 26, 8888, Course.JAVA);
			}else{
				return new Student("麻生希", 26, 8888, Course.JAVA);
			}
		});
		
		//获取原容器中的某个值并返回新容器中
		//map(Function<? super T, ? extends U> mapper)
		Optional<String> map = op.map(Student::getName);
		System.out.println(map.get());
		
		//与map 类似,要求返回值必须是Optional
		//flatMap(Function<? super T, Optional<U>> mapper)
		Optional<String> flatMap = op.flatMap((e)->Optional.of(e.getName()));
		System.out.println(flatMap.get());
	}
}
enum Course{//课程枚举
	JAVA,HTML,PYTHON;
}
class Student implements Comparable<Student>{//学生类
	private String name;
	private int age;
	private double salary;
	private Course course;
    ...
}

接口的默认方法与静态方法

从JDK1.8开始,接口中可以有默认方法,既default修饰的方法,此方法可以让接口的实现类所调用,而接口中的静态方法直接用接口名调用即可

public class Test1 {
	@Test
	public void test01() {
		MyClass myClass = new MyClass();
		myClass.defaultMethod();
		
		I1.staticMethod();
	}
}
interface I1{
	default void defaultMethod(){
		System.out.println("接口中的默认方法");
	}
	public static void staticMethod(){
		System.out.println("接口中的静态方法");
	}
}
class MyClass implements I1{}

接口默认方法的”类优先”原则:

如果一个接口中定义了一个默认方法,而接口实现类的父类定义了一个同名的方法时,选择父类中的方法

接口冲突:

如果一个父接口提供一个默认方法,而另一个接口也提供了一个具有相同名称和参数列表的方法(不管方法是否是默认方法),那么必须覆盖该方法来解决冲突

接口冲突:
一个类实现多个接口,多个接口都有相同名字的默认方法时,实现类必须重写

public class Test1 {
	@Test
	public void test01() {
		MyClass myClass = new MyClass();
		myClass.method();
	}
}
interface I1{
	default void method(){
		System.out.println("I1接口中的默认方法");
	}
}
class Father {
	public void method(){
		System.out.println("Father类中的默认方法");
	}
}
class MyClass extends Father implements I1 {}
public class Test1 {
	@Test
	public void test01() {
		MyClass myClass = new MyClass();
		myClass.method();
	}
}
interface I1{
	default void method(){
		System.out.println("I1接口中的默认方法");
	}
}
interface I2{
	default void method(){
		System.out.println("I2接口中的默认方法");
	}
}
class MyClass implements I1,I2 {
	@Override
	public void method() {
		//I1.super.method();
		I2.super.method();
	}
}

日期组件

组件简介

包路径类名描述
java.time针对日期和时间操作的包
LocalDate用于表示日期的类
LocalTime用于表示时间的类
LocalDateTime用于表示日期时间的类
Instant时间戳类(1970.1.1 0:0:0 到现在的毫秒数)
Period两个日期间隔类
Duration两个时间间隔类
java.time.chrono针对日期时间特殊格式操作的包
JapaneseChronology日本帝国历法系统类
ThaiBuddhistChronology泰国佛教日历系统类
java.time.format针对时间日期时间格式化操作的包
DateTimeFormatter格式化日期时间类
java.time.temporal针对时间矫正操作的包
java.time.zone针对时区操作的包
日期时间格式化类-DateTimeFormatter
public class Test1 {
	@Test
	public void test01() {
		//格式化日期时间类
		
		LocalDateTime ldt1 = LocalDateTime.now();
		
		//获取本地标准的日期时间格式化对象
		DateTimeFormatter dtf1 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
		String strDateTime1 = ldt1.format(dtf1);//格式化时间日期
		System.out.println(strDateTime1);
		
		//自定义日期时间格式化对象
		DateTimeFormatter dtf2 = DateTimeFormatter.
            ofPattern("yyyy年MM月dd日 HH:mm:ss");
		String strDateTime2 = ldt1.format(dtf2);//格式化时间日期
		System.out.println(strDateTime2);
		
		//将指定格式的字符串解析成LocalDateTime对象
		LocalDateTime parse = LocalDateTime.parse("2020年03月12日 11:04:14", dtf2);
		System.out.println(parse);
	}
}
知识点:多线程下使用日期时间类的问题
public class Test01 {
	/**
	 * 知识点:多线程下使用日期时间类的问题
	 */
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
		
		Callable<Date> callable = new Callable<Date>() {
			@Override
			public Date call() throws Exception {
				Date date = sdf.parse("20240529");
				return date;
			}
		};
		
		ArrayList<Future<Date>> list = new ArrayList<>();
		
		ExecutorService pool = Executors.newFixedThreadPool(10);
		for (int i = 1; i <=10; i++) {
			Future<Date> future = pool.submit(callable);
			list.add(future);
		}
		
		for (Future<Date> future : list) {
			System.out.println(future.get());
		}
		
		pool.shutdown();
	}
}//会报错,因为SimpleDateFormat线程不安全

以下是正确的代码:

public class Test02 {
	/**
	 * 知识点:多线程下使用日期时间类的问题
	 */
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMdd");
		
		Callable<LocalDate> callable = new Callable<LocalDate>() {
			@Override
			public LocalDate call() throws Exception {
				
				LocalDate localDate = LocalDate.parse("20240529", dtf);
				return localDate;
			}
		};
		
		ArrayList<Future<LocalDate>> list = new ArrayList<>();
		
		ExecutorService pool = Executors.newFixedThreadPool(10);
		for (int i = 1; i <=10; i++) {
			Future<LocalDate> future = pool.submit(callable);
			list.add(future);
		}
		
		for (Future<LocalDate> future : list) {
			System.out.println(future.get());
		}
		
		pool.shutdown();
	}
}

重复注解

jdk1.8开始可以重复注解

ps:一个类可有多个同样的注解

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;

import java.lang.annotation.Annotation;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

import org.junit.Test;

//重复注解
@Author(name="何老师")
@Author(name="苍老师")
public class Test1<@Author(name="xxx") T> {
	@Test
	public void test01() throws Exception{
		
		//需求1:获取Test1的多个作者注解
		Class<?> ct = Test1.class;
		Author[] as = ct.getAnnotationsByType(Author.class);
		for (Author a : as) {
			System.out.println(a.name());
		}
		
		//需求2:获取method方法中参数里的注解
		Method m = ct.getMethod("method", String.class);
		Annotation[][] parameterAnnotations = m.getParameterAnnotations();
		//获取参数中注解列表(有可能一个参数多个注解)
        for (Annotation[] annotations : parameterAnnotations) {
			for (Annotation an : annotations) {//获取具体注解
				System.out.println(an);
			}
		}
	}
	
	public static void method(@Author(name="波老师") String str){}
}

//作者注解的容器
@Target(TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Authors{
	Author[] value();
}
//作者注解
@Repeatable(Authors.class)
//TYPE_PARAMETER-类型注解:作用泛型
@Target({TYPE, PARAMETER,TYPE_PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@interface Author{
	String name();
}
  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值