1. 本周学习总结

2. 书面作业

Q1.ArrayList代码分析

1.1 解释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;   
    }  
contains方法会遍历数组一遍,如果待查元素o==null,则直接返回数组元素值为null的元素下标;如果不等于null,则调用equals方法,比较后返回相同元素的下标;如果以上两种情况都不符,返回-1.

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

public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

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

先调用rangeCheck方法检查要删除的位置index是否超过size,如果超过就报错IndexOutOfBoundsException;如果未超过,就进行删除操作,每次删除一个元素,后面的元素自动全部向前移动,最后一个元素置为null.

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

不需要,因为其参数为Objcet类型的对象,Objcet类又是所有类的父类,所以不需要考虑。

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

public boolean add(E e) {
    ensureCapacityInternal(size + 1);  // ensureCapacityInternal用来调整容量
    elementData[size++] = e;
    return true;
}  
private void ensureCapacityInternal(int minCapacity) {
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }

    ensureExplicitCapacity(minCapacity);
}
    modCount++;
    // overflow-conscious code
    if (minCapacity - elementData.length > 0) //如果超出容量,则调用grow方法增加容量
        grow(minCapacity);
}   
private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1); //增加原来容量的一半(右移一位就是/2),也就是说新List的容量是旧的1.5倍
    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); //用Arrays.copyOf()方法来生成新的数组,然后将旧数组的数据拷贝到新数组中去。
}  

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

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

因为rangeCheck方法只是在remove操作中用来判断是否超出了界限。而在remoe外部并不需调用该方法,所以声明为private而不声明为public。

Q2.HashSet原理

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

HashSet用链表数组实现,每个列表被称为桶.
若要将元素加入HashSet中,首先要调用该对象x的hashCode方法,计算出x的哈希码,根据哈希码查找到对应的桶。然后如果桶中已有其他元素,则调用加入对象x的equals方法与已有元素进行比较,如果比较结果为假,则将x插入桶中。如果比较结果为真,则用新的值替换旧的值。

Q3.ArrayListIntegerStack

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

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

A:实现类内部的数组不同,ArrayIntegerStack采用创建时指定大小的固定数组,ArrayListIntegerStack采用ArrayList存储,在数组容量不足时会自动扩容。
B:ArrayIntegerStack在出栈时要移动top指针,ArrayListIntegerStack则是调用remove方法。

3.2 简单描述接口的好处.

接口是一系列方法的声明而没有方法的实现,这些方法的实现由调用他们的类动态的决定他们具有的行为(功能),从而让我们更灵活的编程。

Q4.Stack and Queue

4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。

import java.util.*;

class Stack<S>{
	private LinkedList<S> s1=new LinkedList<S>();
	public void push(S v){
		s1.addFirst(v);
	}
	public S peek(){
		return s1.getFirst();
	}
	public S pop(){
		return s1.removeFirst();
	}
	public boolean empty(){
		return s1.isEmpty();
	}
	public String toString(){
		return s1.toString();
	}
}

public class Main201521123025 {
	public static void main(String[] args){
		Stack<Character> stack=new Stack<Character>();
		Scanner in = new Scanner(System.in);
	    String str = in.next();
	    for(int i=0;i<str.length();i++){
	    	stack.push(str.charAt(i));
	    }
	    boolean isPalindrome = true;
		for(int j=0;j<str.length();j++){
			if(stack.pop()!=str.charAt(j)){
				isPalindrome=false;
				break;	
			}
		}
		 if (isPalindrome) {
	            System.out.println("yes");
	        } 
		 else {
	            System.out.println("no");
	        }
	}
}

4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)

入队

for(i=0;i<n;i++){
    x=in.nextInt();
    if(x%2==1) list1.add(x);//奇数进入A窗口
    else list2.add(x);//偶数进入B窗口
}

出队

    while(list1.size()>1)
        System.out.print(list1.poll()+" ");
    if(list1.size()==1){
            System.out.print(list1.poll());
            }
    while(list2.size()>1)
        System.out.print(list2.poll()+" ");
    if(list2.size()==1){
            System.out.print(list2.poll());
            }
}

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

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

public class Main052{
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int x=0;
		String str;
		Set<String> strsetree=new TreeSet<String>();
		for(int i=0;;i++){
			str=in.next();
			if(str.equals("!!!!!")) break;
			else strsetree.add(str);
		}
		System.out.println(strsetree.size());
		for(String s:strsetree){
			x=x+1;
			System.out.println(s);
			if(x==10) break;
		}
	}
}

5.1 实验总结

set集合的对象是不重复的,TreeSet有排序功能。

Q7.面向对象设计大作业-改进


7.1 完善图形界面(说明与上次作业相比增加与修改了些什么)

增加了菜单选项

7.2 使用集合类改进大作业

利用Set储存用户的信息就不会出现重复错误

3. 码云上代码提交记录及PTA实验总结