201621123061《Java程序设计》第八次学习总结

1. 本周学习总结

以你喜欢的方式(思惟导图或其余)概括总结集合相关内容。

2. 书面做业

1. ArrayList代码分析

1.1 解释ArrayList的contains源代码

源代码以下:javascript

public boolean contains(Object o) {
        return indexOf(o) >= 0; 
    }

public int indexOf(Object o) {              
        if (o == null) {                    
            for (int i = 0; i < size; i++)   
                if (elementData[i]==null)    
                    return i;                
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

ArrayList的contains方法调用了indexOf方法。indexOf方法是经过对ArrayList型的对象的遍历,假如对象o找到和它相等的值,则放回该值的位置,不然返回-1。contains方法则是根据indexOf(o) >= 0是否成立来判断,若成立则返回true,即包含,不成立返回false,即不包含。java

1.2 解释E remove(int index)源代码

源代码以下:数组

public E remove(int index) {
    rangeCheck(index);          //检查是否在范围内

    modCount++;                    //初始值为0
    E oldValue = elementData(index);     //保存旧数据

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);         //将移除位置以后全部的元素都向前挪动一个位置
    elementData[--size] = null;        //将最后一个元素置为空
    return oldValue;                      
}
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

首先判断要删除的位置是否超出的范围:若是超出,则抛出异常,不然删除该位置的元素,而且将移除位置以后全部的元素都向前挪动一个位置,将最后一个元素置为空。函数

1.3 结合1.1与1.2,回答ArrayList存储数据时须要考虑元素的具体类型吗?

不须要。ArrayLis存储是用Object[]数组实现的,Object是全部类的父类,因此不须要考虑元素的类型。学习

1.4 分析add源代码,回答当内部数组容量不够时,怎么办?

源代码以下:this

public boolean add(E e) {
        ensureCapacityInternal(size + 1);            // 确保下一个元素进来有空间
        elementData[size++] = e;
        return true;
    }

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // DEFAULT_CAPACITY = 10,默认长度为10
        }

        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);                       
    }

private void grow(int minCapacity) {                         //增长容量
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);  //增长原来容量的一半。
        if (newCapacity - minCapacity < 0)             //判断容量是否足够,够的话就直接以这个长度建立数组
            newCapacity = minCapacity;                       
        if (newCapacity - MAX_ARRAY_SIZE > 0)                //若是不够,再扩充
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//最后将原来的复制到新的数组中  
    }

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;                                   //MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
    }

1.5 分析private void rangeCheck(int index)源代码,为何该方法应该声明为private而不声明为public?

源代码以下:code

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

rangeCheck方法用来判断是否超出容量范围,没有返回值,假如超出范围了就直接抛出异常。使用private是由于用户不须要知道rangeCheck方法是如何操做,由于在进行各个方法的调用时须要该方法时就会自动被调用,开发者不须要本身手动进行判断是否越界。对象

2. HashSet原理

2.1 将元素加入HashSet(散列集)中,其存储位置如何肯定?须要调用那些方法?

首先要调用hashCode方法获得相应的哈希值,而后对哈希值进行计算,算出在哈希表中对应的位置。若是对应的位置上没有值,则将元素放在该位置上,若是该位置上有别的值,则调用equals方法比较位置上的值和要加入的元素的值,若是为true,则说明两个值相等,而HashSet不容许有重复的值,则用新元素代替就元素,若是结果为false,就经过散列冲突的解决办法解决。blog

2.2 将元素加入HashSet中的时间复杂度是多少?是O(n)吗?(n为HashSet中已有元素个数)

将元素加入HashSet中不须要遍历,时间复杂度为O(1)。排序

2.3 选作:尝试分析HashSet源代码后,从新解释2.1

源代码以下:

public boolean contains(Object o) {
    return map.containsKey(o);
}

public boolean containsKey(Object key) {    //若是此映射包含对于指定键(key)的映射关系,则返回true

    return getEntry(key) != null;  
} 
final Entry<K,V> getEntry(Object key) { //经过key获取value
    int hash = (key == null) ? 0 : hash(key.hashCode());//
    for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { 
        Object k;    
        if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))  
            return e;  
    }
    return null; 
}

调用contains方法,contains又调用map.containsKey方法,该方法又调用getEntry方法来获取value。containsKey对返回的Keyvalue判断,若是为空在返回false,不然返回true。

3. ArrayListIntegerStack

题集jmu-Java-05-集合之ArrayListIntegerStack

3.1 比较本身写的ArrayListIntegerStack与本身在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目自定义接口ArrayIntegerStack,有什么不一样?(不要出现大段代码)

  • ArrayListIntegerStack利用ArrayList实现栈的存储,ArrayList是长度可变化的数组,没必要考虑栈满的状况。
  • ArrayIntegerStack利用长度不可变数组来实现栈的存储,说数组不可变,实际上是由于一开始就要设定好数组的长度,须要考虑栈满的状况。

    3.2 结合该题简单描述接口的好处,需以3.1为例详细说明,不可泛泛而谈。

    接口对类的全部共性方法进行声明,实现这个接口的类再对方法进行重写。在3.1中,ArrayListIntegerStack和ArrayIntegerStack都有共同的方法,可是对这些方法的实现,对栈的存储方式不同(重写的方法又不同)。接口的方法在不一样的类中实现,实现起来又能有不同的功能,这样会比较方便,弥补了类不能被多继承的缺憾。

4. Stack and Queue

4.1 编写函数判断一个给定字符串是不是回文,必定要使用栈(请利用Java集合中已有的类),但不能使用java的Stack类(具体缘由本身搜索)与数组。请粘贴你的代码,类名为Main你的学号。

4.2 题集jmu-Java-05-集合之银行业务队列简单模拟(只粘贴关键代码)。请务必使用Queue接口,并说明你使用了Queue接口的哪个实现类?


使用了Queue接口的实现类Deque。

5. 统计文字中的单词数量并按单词的字母顺序排序后输出

题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (做业中不要出现大段代码)

5.1 实验总结


这题关键是要用TreeSet,能够自动排序。

3.码云及PTA

题目集:jmu-Java-05-集合

3.1. 码云代码提交记录

在码云的项目中,依次选择“统计-Commits历史-设置时间段”, 而后搜索并截图

3.2 截图PTA题集完成状况图

须要有两张图(1. 排名图。2.PTA提交列表图)

3.3 统计本周完成的代码量

须要将每周的代码统计状况融合到一张表中。

周次 行数 新增行数 文件数 新增文件数
1 91 91 5 5
2 504 413 18 13
3 1092 588 28 10
5 1158 129 34 6
6 1539 381 40 6
7 2023 484 49 9
8 2477 454 57 8
9 2709 232 63 6
相关文章
相关标签/搜索