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

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

1. 本周学习总结

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

2.书面做业

1. ArrayList代码分析

1.1 解释ArrayList的contains源代码

答:算法

  • ArrayList的contains的源代码以下:
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;
    }
 public boolean equals(Object obj) {
    return (this == obj);
    }
  • 从上能够看出,contians方法是先判断对象是否为null,对象为空,就返回列表中第一个null的索引,若是对象不为空就与列表中元素逐一对比,在此过程当中会调用equals方法来比较两个对象的引用是否相同,最终没有包含该对象的时候返回-1。数组

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

    答:
  • remove源代码
public E remove(int index) {
        RangeCheck(index);

        E oldValue = (E) elementData[index];
      
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved); 
        elementData[--size] = null; 
        return oldValue;
    }
  • 经过RangeCheck(index)检查index是否在索引范围内,知足条件,将要删除的元素赋给oldValue,再将该元素删除,最后返回oldValue。
    当index不在索引范围时,会抛出异常 IndexOutOfBoundsException(outOfBoundsMsg(index))。
 private void rangeCheck(int index) {         if (index >= size) 
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));     
}

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

答:函数

  • ArrayList构造函数源码
public ArrayList() {  
       super();       
      this.elementData = EMPTY_ELEMENTDATA;//EMPTY_ELEMENTDATA是个空的Object[],将elementData初始化,elementData也是Object[]类型
    }

在构造函数中,ArrayList类中定义了elementData数组(private transient Object[] elementData)来存放对象,这个数组是Object类型,即不管放入什么引用类型,都会包装成Object类型存入,因此无需考虑具体类型。学习

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

答:add()有两个方法,boolean add(E),void add(int ,E)this

public boolean add(E e) {    
    
        ensureCapacityInternal(size + 1);  
        elementData[size++] = e;
        return true;
    }
private void ensureCapacityInternal(int minCapacity) {
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        ensureExplicitCapacity(minCapacity);
    }

要添加一个元素,先判断size+1(size是数组中数据的个数)这个个数数组可否放得下,用ensureCapacityInternal()这个方法判断数组长度(数组.length())可否够用。当数组为空时没有长度,就默认minCapacity变成10,即默认数组大小为10。设计

  • 经过 ensureExplicitCapacity(minCapacity)确认实际的容量。(elementData不是空的数组时,minCapacity=size+1,表明elemenData增长后的实际数据个数,用minCapacity与elementData.length比较)。当内部数组不够用时,ArrayList会 自动扩展数组大小。
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
      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)//空数组时,真正初始化elementData大小为10
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)y
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);  //肯定新容量,拷贝数组,改变容量大小
    }

扩容时,会将原来数组的大小给oldCapacity,newCapacity是1.5倍的oldCapacity。newCapacity - MAX_ARRAY_SIZE > 0判断newCapacity是否超过最大容量限制,超过就将能给的最大值给newCapacity,此时肯定新容量大小,就拷贝原来数组,并改变容量大小。3d

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

答:rangeCheck用于判断数组是否越界,只有本类移除、增添等方法中须要使用,就用private将其封装起来,用户只须要知道移除,增添等方法,不须要知道具体的实现过程。指针

2. HashSet原理

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

答:经过哈希算法进行肯定存储位置。先调用hashCode()方法,计算出哈希值,找到对应的链表,调用equals方法判断该链表中是否有重复的对象。code

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

答:时间复杂度为O(1)。经过哈希算法得出位置就将元素直接添加进表中,这个过程的时间复杂度为O(1)。

3. ArrayListIntegerStack

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

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

答:

  • 实现类中存储数据形式不一样,自定义接口ArrayIntegerStack中用Integer数组,而ArrayListIntegerStack中使用集合List的ArrayList类。
  • 自定义接口ArrayIntegerStack中容易发生数组越界的问题,ArrayListIntegerStack中动态数组ArrayList会自动扩容,不用担忧会发生越界现象。
  • ArrayIntegerStack中须要多一个top指针来存取元素,ArrayListIntegerStack则不用,经过ArrayList存放元素极大便利了栈的操做。

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

答:接口IntegerStack与上次自定义接口相同, ArrayListIntegerStack实现了该接口。此时咱们无需再从新写一个栈并重写实现方法。实现该接口后,咱们只需编写具体方法就能够了,减小没必要的代码量,让代码更为灵活。

4. Stack and Queue

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

答:

  • 自定义栈,用ArrayList存储字符
public class CharatorStack {
    private List<Character> list;

    public CharatorStack() {
        List<Character> list=new ArrayList<>();
        this.list = list;
    }
    //入栈
    public void push(char c) { 
        list.add(c);
    }
     //出栈,如栈为空,则返回null。
        public Character pop(int i) {
            if(list.size()==0)
               return null;
            return list.remove(i);//出栈时注意移除出栈元素
        }
        //得到栈顶元素,如栈顶为空,则返回null。注意:不要出栈
        public Character peek() {
            if(list.size()-1==0)
               return null;
            return list.get(list.size()-1);
        }
         //如过栈为空返回true
        public boolean empty() {
           if(list.size()==0)
                return true;
           else
               return false;
        }
}
  • 实现类
public class Main201621123003 {

    public static void main(String[] args) {
    Scanner sc=new Scanner(System.in);
    CharatorStack stack=new CharatorStack();

    while(true){
    String str=sc.next();
    if(str.equals("end"))
        break;
    char[] c=str.toCharArray();
    for (int i = 0; i < str.length(); i++) {
        stack.push(c[i]);
    }
    int flag=0;
  for (int i = 0; i < c.length; i++) {
    if(c[i]==stack.pop(c.length-i-1)){
        flag=1;
        }
    else{
        flag=0;
    }
}
  if(flag==1)
  {
      System.out.println("YES");
  }
  else{
      System.out.println("NO");
  }
    }
    }

}
  • 运行

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

答:

  • 使用Queue接口,并用LinkedList来实现。
  • 主要代码
if (Integer.parseInt(strs[0]) <= 1000) {
            for (int i = 1; i < strs.length; i++) {
                int temp1 = Integer.parseInt(strs[i]);
            if (temp1 % 2 == 0) {
                    arrBQueue.add(temp1);
                } else {
                    arrAQueue.add(temp1);
                }
            }
        }
        int i=0;
        if(!arrAQueue.isEmpty())
            System.out.print(arrAQueue.poll());
        else {
            System.out.print(arrBQueue.poll());
        }
        
        while(!arrAQueue.isEmpty()||!arrBQueue.isEmpty()) {
            i++;
            if(i%2==0) {
                if(!arrAQueue.isEmpty())
                    System.out.print(" "+arrAQueue.poll());
            }else {
                if(!arrAQueue.isEmpty())
                    System.out.print(" "+arrAQueue.poll());
                if(!arrBQueue.isEmpty())
                    System.out.print(" "+arrBQueue.poll());
                
            }
        }

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

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

5.1 实验总结

答:该题主要使用TreeSet集合存放不重复的单词,并利用TreeSet完成按字母顺序排序。

6. 选作:统计文字中的单词数量并按出现次数排序

题集jmu-Java-05-集合之5-3 统计文字中的单词数量并按出现次数排序(不要出现大段代码)

6.1 伪代码

答:

  • 一、创建Map<String,Integer> words=new HashMap<>();
  • 二、循环将单词做为键对象,次数做为值对象存入words集合中;
  • 三、创建List存入Map.Entry对象。
  • 四、从新定义Collections.sort中的compare方法。
  • 五、输出List

    6.2 实验总结

    答:该题难点是如何实现单词次数按照降序排序,若是次数相同,则按照键值的字母升序排序。先将Map集合中每个对象存入List,再从新定义compare方法。

    3.码云及PTA

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

3.1. 码云代码提交记录

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

3.2 截图PTA题集完成状况图

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

3.3 统计本周完成的代码量

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

周次 总代码量 新增代码量 总文件数 新增文件数
1 0 0 0 0
2 0 0 0 0
3 0 0 0 0
4 0 0 0 0
5 739 739 16 16
6 1084 345 28 12
7 1180 96 30 2
8 1627 447 35 5
9 1986 359 44 9
相关文章
相关标签/搜索