一、泛型


1、逆变和协变

逆变和协变发生在带有泛型的类型引用的相互转换上。 比如说函数参数的的传递,引用的传递

(1)逆变

Java语法? super X

(2)协变

Java语法? extends X

(3)方法的参数和返回值

  • 参数遵循逆变法则
  • 返回值遵循协变法则

(4)Function的逆变和协变

原则:参数类型逆变,返回值类型协变

例子:

class A{}
class B extends A{}

void foo(Function<? super A, ? extends A> func){
	Object o = func.apply(new B());
}

Function<Object,B> cb = o->new B();
Function<? super A, ? extends A> cb1 = (Object b) -> new B();
Function<? super A, ? extends A> cb2 = cb;
Object o = cb2.apply(new B());

foo(cb);
foo(cb1);

(5)常规用法

  • 参数类型逆变,返回值类型协变
  • 要从泛型类取数据时,用extends;(也就是返回值)
  • 要往泛型类写数据时,用super;(也就是函数参数)

2、Either实现小例子

需求:某些函数可能需要返回正确数据或者错误信息,但又不想使用异常,因为错误信息,在上层也是正常的业务,所以需要一个容器来容纳错误对象或者正常返回对象

实现:Either容器:

  • 允许可以存放两个中类型的对象,一个是left:L(错误对象),一个是right:R(正确返回的对象)
  • 同一个实例只允许存放两种类型中的一个

    public class Either<L,R> {
    	private final L left;
    	private final R right;
    	private final boolean isLeft;
    
    	private Either(L left, R right, boolean isLeft){
    		this.left = left;
    		this.right = right;
    		this.isLeft = isLeft;
    	}
    
    	public static <L,R> Either<L, R> left(L left){
    		return new Either<>(left, null, true);
    	}
    
    	public static <L,R> Either<L, R> right(R right){
    		return new Either<>(null, right, false);
    	}
    
    	public boolean isLeft() {
    		return isLeft;
    	}
    
    	public boolean isRight() {
    		return !isLeft;
    	}
    
    	public Optional<L> left(){
    		return Optional.of(left);
    	}
    
    	public Optional<R> right(){
    		return Optional.of(right);
    	}
    
    	public <T> Either<L, T> map(
    			Function<? super R, ? extends T> rFunc){
    		if(isLeft) {
    			return new Either<>(left, null, true);
    		} else {
    			return new Either<>(null, rFunc.apply(right), false);
    		}
    	}
    
    	public <T> T match(
    			Function<? super L, ? extends T> lFunc,
    			Function<? super R, ? extends T> rFunc){
    		if(isLeft) {
    			return lFunc.apply(left);
    		} else {
    			return rFunc.apply(right);
    		}
    	}
    
    	public void apply(Consumer<? super R> rFunc){
    		if(!isLeft){
    			rFunc.accept(right);
    		}
    	}
    }

三、一条语句初始化集合


1、单元素集合

import java.util.Collections;

Set<Integer> singleton = Collections.singleton(1);
List<Integer> singletonList = Collections.singletonList(1);
Map<Integer, Integer> singletonMap = Collections.singletonMap(1, 1);

注意这种方式创建的都是不可变的集合

2、利用Arrays.asList初始化

	private static Set<String> KEY_NAMES = new HashSet<String>(Arrays.asList("paths", "ignorePaths", "allowUsers", "reviewUsers","qcReviewUsers"));

3、利用匿名子类+动态代码块

	private static Set<String> set = new HashSet<String>() {{
		add(1);
		add(2);
		add(3);
		add(4);
	}}