CS61B - Lec 13 - Syntax 1

这个系列的讲座主要讲的是最后剩下的一些java语法,之后就不会涉及到java操作教学了。(java学完了hh)
昨晚完成了proj1,应用了test方法和interface。看到test变绿真的很爽。继续冲!

Generic Basics, Autoboxing, Widening

Generic

Generic就是之前实现的List里可以包含任意类型的操作:

import java.util.ArrayList;

public class BasicArrayList<Item> {
	...
	public static void main(String[] args) {
		List<String> l = new ArrayList<>();
}

但是<>里放的只能是引用类型,如果这样就会报错

List<int> l = new List<>();

原因是int是primitive type,必须替换成reference type - Integer。
在这里插入图片描述
如图,每种primitive type都有与之对应的reference type,称之为wrapper class(把一种primitive type包装了起来)。

然而,因为generic要求的是一个类,那我们对List进行操作的时候,不是只能这样了么:

List<Integer> l = new Arraylist<>();
l.add(new Integer(5));
l.add(new Integer(6));
int first = l.get(0).valueOf();

多麻烦啊,所以java提供了解决方案。

Autoboxing(conversion)

java自动会实现两中类型间的转换,所以我们一般是这么写代码的:

List<Integer> l = new Arraylist<>();
l.add(5);
l.add(6);
int first = l.get(0);

即便向Integer形参里传递了int类型,编译还是会通过。
在这里插入图片描述
注意:数组不能转换。
在这里插入图片描述
上题的答案是e, 160 bits。当引用类型Integer声明时,分配了一个64位的地址空间,然后作为一个对象,起始有64位不知道有啥的空间,加上32位的一个int。

Primitive Widening

在这里插入图片描述
如图,int类型就可以传递给一个wider range的primitive type(如 double),而doule想传递给int就得进行casting。

Immutability

主要是说final关键字。
在这里插入图片描述
final的意思是该变量的值只能初始化一次,然后就不可改变。(如Integer中的int)
在这里插入图片描述
优点和缺点显而易见。最下方的例子说的是仅仅声明一个引用类型是final,不代表该引用类型指向的对象是final,依然可以对该对象进行操作,只是d的地址就不变了。

Defining Generic Classes

在这里插入图片描述
首先初始化。以数组作为核心结构,这里不需要考虑resize的问题。

public class ArrayMap<K, V> implements Map61B<K, V> {

    private K[] keys;
    private V[] values;
    int size;

    public ArrayMap() {
        keys = (K[]) new Object[100];
        values = (V[]) new Object[100];
        size = 0;
    }
}

然后,写返回键值的index的helper方法

private int keyIndex(K key) {
        for (int i = 0; i < size; i += 1) {
            if (keys[i].equals(key)) { //对引用类型来说,如果==只是比较地址,这样才能比较值
                return i;
            }
        }
        return -1; //如果没有key,返回-1
    }

put方法,功能是如果存在key,则重新写入value;如果不存在则在末尾写入key和value。

public void put(K key, V value) {
        int index = keyIndex(key);
        if (index == -1) {
            keys[size] = key;
            values[size] = value;
            size += 1;
            return;
        }
        values[index] = value;
    }

containKey,和keyIndex差不多

public boolean containKey(K key) {
        int index = keyIndex(key);
        return index > -1;
    }

key,返回由键值组成的List

public List<K> keys() {
        List<K> keylist = new ArrayList<>();
        for (int i = 0; i < size; i += 1) {
            keylist.add(keys[i]);
        }
        return keylist;
    }

get(key),有问题,之后会改进

/** Crash when there is no key in ArrayMap. */
    public V get(K key) {
        int index = keyIndex(key);
        return values[index];
    }

Generic Methods

在这里插入图片描述
这里要改进之前的get方法,以及加入一个maxKey方法。并且直接通过MapHelper类名调用这些方法,也就是说都是static的。

public class MapHelper {
    public static V get(Map61B<K, V> sim, String key) 
    ...

实现MapHelper.get的时候,出现了问题,编译器不知道K和V是什么。而之前一直都是这么干的:

public class MapHelper<K, V> {
    public V get(Map61B<K, V> sim, String key) 
    ...

但是,如果这样就必须声明对象了:

MapHelper<String, Integer> map = new MapHelper()

最终要实现的,是这样的:
在这里插入图片描述
咋整呢?这样就行了。

public static <K, V> V get(Map61B<K, V> sim, K key) {
        if (sim.containKey(key)) {
            return sim.get(key);
        }
        return null;
    }

在返回类型前加上<K, V>,表明KV类型只对该方法起作用。

接着,实现maxKey方法,发现碰到了和之前差不多的问题

public static <K, V> K maxKey(Map61B<K, V> map) {
        List<K> keylist = map.keys();
        K largest = keylist.get(0);
        for (K k: keylist) {
            if (k > largest) {
                largest = k;
            }
        }
        return largest;
    }

同样,需要实现两个对象比大小,想到了之前的Comparable接口的compareTo方法

k.compareTo(largest) > 0

这样会报错,因为编译器在此时并不知道K是哪个类,不知道有没有或者调用哪个compareTo方法。因此,需要保证K是继承自Comparable接口的,具体语法是这样:

public static <K extends Comparable<K>, V> K maxKey(Map61B<K, V> map)

其实也很好理解,就是“类K必须继承Comparable接口”的意思。

还有一个问题,为什么这里不用implement用extend呢?

因为这里的extend是一种说明,说明类继承了Comparable这个事实,而不是定义K要实现Comparable里所有的方法,要求要在K里进行实现。
Josh更倾向于用isASubtypeOf这个关键字。
在这里插入图片描述

准备开始搞proj2了,听说非常难。

发布了20 篇原创文章 · 获赞 0 · 访问量 170

猜你喜欢

转载自blog.csdn.net/fourier_transformer/article/details/105219483