1. 本周学习总结
2. 书面作业
1.ArrayList代码分析
1.1 解释ArrayList的contains源代码
分析:该方法实现了ArrayList数组的遍历,从而确定所查内容是否存在
1.2 解释E remove(int index)源代码
分析:找到要移除的第index个元素,从第index+1个元素开始,索引全部往前移动一位,再将原来最后一个元素置空
1.3 结合1.1与1.2,回答ArrayList存储数据时需要考虑元素的类型吗?
答:不需要考虑。基本数据类型就不说了。说说类类型,ArrayList中的数组是用Object定义的,在Java中,每个类都是由Object扩展而来,即每个类都缺省继承Object类。
1.4 分析add源代码,回答当内部数组容量不够时,怎么办?
add方法用于添加一个元素到当前列表的末尾,
public boolean add(E e) {
ensureCapacityInternal(size + 1); //只要保持有size+1个容量就能保证加入成功
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);//顾名思义,保证容量够用
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);//如果需要的容量比当前容量大,则调用grow方法
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//new=1.5*old
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);//copyOf,拷贝到新的数组中了
}
1.5 分析private void rangeCheck(int index)源代码,为什么该方法应该声明为private而不声明为public?
隐藏对象的内部实现细节,即封装。在面向对象编程的Java中,我们只需要知道ArrayList这个类中有remove这个方法,而不需要知道它是怎么实现的。就像我们开车,只需要知道踩油门加速、踩刹车减速,而不需要知道发动机具体是怎么工作的
2.HashSet原理
2.1 将元素加入HashSet(散列集)中,其存储位置如何确定?需要调用那些方法?
HashSet是个链表数组。每一个数组元素就是一个列表,我们称为散列表元 。
确定位置调用了hashCode方法,得到一个hash码,从而确定元素的存储地址,还调用equals方法,判断对象在数组中是否存在,存在则不添加。
2.2 选做:尝试分析HashSet源代码后,重新解释1.1
HashSet其实是通过HashMap实现的,添加也是通过put方法。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
再看put方法
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict){
••••••//so many code
}
//不过大概意思就是计算散列值,找到对应下标,从对应列表里面进行查找,如果有键相同的替换,没有就追加
3.ArrayListIntegerStack
题集jmu-Java-05-集合之5-1 ArrayListIntegerStack
3.1 比较自己写的ArrayListIntegerStack与自己在题集jmu-Java-04-面向对象2-进阶-多态、接口与内部类中的题目5-3自定义接口ArrayIntegerStack,有什么不同?(不要出现大段代码)
数据结构不同,ArrayListIntegerStack使用ArrayList实现,而ArrayIntegerStack使用Integer数组实现,虽然本质上都是采用数组的方式,但是前者不需要考虑栈满的情况,能够动态地根据需要添加,而后者却需要事先定义好栈存大小,且不能更改。
3.2 简单描述接口的好处.
好处就是,你能用、我能用,只要有需要,就能用,而且能很好地辨别出谁在用。扩展性、灵活性强,一个接口多个实现,效率提高
4.Stack and Queue
4.1 编写函数判断一个给定字符串是否是回文,一定要使用栈,但不能使用java的Stack类(具体原因自己搜索)。请粘贴你的代码,类名为Main你的学号。
Java中的Stack类不是一个纯粹的Stack,其继承自Vector类,也就是说Vector类的所有成员Stack都能使用,这样造成了Stack可以不用采用LIFO的规则。
package chpt04;
import java.util.*;
interface CustomStack<E> {//自定义栈
public E push(E item);//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。
public E pop(); //出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
public E peek(); //获得栈顶元素,如果为空,则返回null.
public boolean empty(); //如果为空返回true
public int size(); //返回栈中元素个数
}
class ArrayListIntegerStack<E> implements CustomStack<E> {
private List <E>list;
public ArrayListIntegerStack() {
list=new ArrayList<E>();
}
@Override
public E push(E item) {
//如果item为null,则不入栈直接返回null。如果栈满,也返回null。如果插入成功,返回item。
if(item==null)
return null;
list.add(item);
return item;
}
@Override
public E pop() {
//出栈,如果为空,则返回null。出栈时只移动栈顶指针,相应位置不置为null
if(list.isEmpty())
return null;
return list.remove(list.size()-1);
}
@Override
public E peek() {
//获得栈顶元素,如果为空,则返回null.
if(list.isEmpty())
return null;
return list.get(list.size()-1);
}
@Override
public boolean empty() {
//如果为空返回true
return list.isEmpty();
}
@Override
public int size() {
//返回栈中元素个数
return list.size();
}
@Override
public String toString() {
return list.toString() ;
}
}
public class Main2015023 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
CustomStack<String> stack=new ArrayListIntegerStack<String>();
String st=sc.next();
String stExchange="";
for(int i=0;i<st.length();i++){
String l=st.substring(i, i+1);//按字符顺序入栈
stack.push(l);
}
for(int j=0;j<st.length();j++){
String x=stack.pop();//按占内存数据出栈
stExchange+=x;
}
if((st.equals(stExchange))==true)//比较先后两串字符串,若相同则为回文
System.out.println("该字符串是回文");
}
}
4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)
for (int i = 1; i <= n; i++) {
int num = sc.nextInt();
if (num % 2 == 0) {
linkB.add(num);//偶数
} else {
linkA.add(num);//奇数
}
}
while(!listA.isEmpty()&&!listB.isEmpty()){
if(!listA.isEmpty()){
System.out.print(listA.poll()+" ");//第一次
if(!listA.isEmpty()){
System.out.print(listA.poll()+" ");//第二次
}
}
System.out.print(listB.poll()+" ");//奇二偶一
}
然后将剩下的A队列或B队列全部出队
5.统计文字中的单词数量并按单词的字母顺序排序后输出
题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码)
5.1 实验总结
出现的单词统计时只需统计一次,因此可以用Set来实现存储,而Set的实现类中TreeSet可以对对象进行排序
6.选做:加分考察-统计文字中的单词数量并按出现次数排序
题集jmu-Java-05-集合之5-3 统计文字中的单词数量并按出现次数排序(不要出现大段代码)
6.1 伪代码
List<Map.Entry<String, Integer>> strS =new ArrayList<Map.Entry<String, Integer>>(str.entrySet());
Collections.sort(strS, new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
return (o2.getValue() - o1.getValue());
}
});
6.2 实验总结
总的来说和5-2差不多,不过需要统计每个单词出现的次数,所以用Map来实现String-->Integer 的映射,value存储key出现的次数值。再通过ArrayList实现Comparator接口(这里我用的是匿名内部类),对value进行排序。同样的Map的实现类里有TreeMap可以对key进行排序。
3. 码云上代码提交记录及PTA实验总结
题目集:jmu-Java-05-集合