• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
Tonya
博客园    首页    新随笔    联系   管理    订阅  订阅
201521123007《Java程序设计》第7周学习总结

1. 本周学习总结


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;
    }

可以看到,contains的源代码非常简单,返回indexOf(o) >= 0,调用了indexOf()方法;

我们先来了解一下indexOf()方法的实现:

  • 返回第一次出现的指定元素的索引
  1. 在这个列表中,如果该列表不包含指定元素返回-1
  2. 如果指定元素为null,则遍历列表找出null的索引位置并返回
  3. 若指定元素不为null,同样遍历列表找出并返回指定元素的第一次索引位置

再来看contains方法的实现:

  • 如果列表包含指定元素返回true,否则返回false
  1. 如果indexOf(o) >= 0则表明在列表中能找出指定元素o的索引位置
  2. 若indexOf(o)=-1则在列表中不存在指定元素,返回false

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

以下是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;
    }
  • 首先用rangeCheck(index)方法检查传进来的指标index是否越界,要知道rangeCheck方法无返回值,if(index>=size),抛出IndexOutOfBoundsException(outOfBoundsMsg(index));
  • modCount++;这个列表的次数已经结构修改。结构修改是那些改变列表的大小,或扰乱它在这样一个时尚的迭代过程中可能产生不正确的结果。(这个姑且看看,不是很懂)
  • numMoved的值表示被删除元素后面的元素个数
  • 接着if后的代码作用是把指标后的元素按位往前挪一位,最后一个元素设为null
  • 返回删除的元素

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

答案是不需要,可以通过以下例子来说明:

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

以下是add的源代码:

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

    public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

有两种常用的add方式,一是直接在列表末尾添加新元素,二是在指定位置上插入新元素;
从以上代码可以看出,无论是哪种add方法,在ArrayList中都不存在内部数组容量不够的问题,因为add方法会使数组容量自动增加。

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

封装思想,将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,用户不需要知道rangeCheck方法如何实现,只需要知道结果就行。

2. HashSet原理

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

先来看看HashSet的add方法如何实现:

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
public V put(K key, V value) {
    return putVal(hash(key), key, value, false, true);
}

Set集中没有重复对象,如果添加Set集中的相同对象,则新对象覆盖原对象;
可以看出add方法调用了map.put()方法,put方法又调用了putVal方法,具体实现不管,但是可以看出调用了hash()函数,而hash函数可以帮助找到对象的索引位置。

3. ArrayListIntegerStack

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

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

首先相同之处是都实现了IntegerStack接口,继承了接口中的各种方法:

interface IntegerStack {
	public Integer push(Integer item);
	public Integer pop();
	public Integer peek();
	public boolean empty();
	public int size();
}

再者不同之处是ArrayListIntegerStack内部实现用ArrayList列表,ArrayIntegerStack内部实现用Array数组。
就光Array数组必须设置容量而ArrayList列表不需要来说,ArrayListIntegerStack就省事儿多了。
因为在重写各种方法时列表不需要考虑是否越界的问题,而数组需要多考虑这一问题。

3.2 简单描述接口的好处.

  1. 接口实现扩展功能,让不同的类之间有了联系,却不相互干涉;
  2. 类可以实现多接口,接口中的方法可以不全部实现,体现接口的灵活性。

4. Stack and Queue

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

import java.util.LinkedList;
import java.util.Scanner;

public class Main201521123007 {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String str = in.next();
		String[] s = str.split("");
		LinkedList<String> stack = new LinkedList<String>();
		for (String string : s) {
			stack.add(string);
		}
		int i = 0;
		for (; i < s.length / 2; i++) {
			if (stack.pollLast().equals(s[i])) {
				continue;
			} else {
				System.out.println(str + "不是回文");
				break;
			}
		}
		if (i == s.length / 2)
			System.out.println(str + "是回文");

		in.close();
	}
}

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

		Queue<Integer> q1=new ArrayDeque<Integer>();
		Queue<Integer> q2=new ArrayDeque<Integer>();
		for (int i = 0; i < n; i++) {
			if(q1.size()==2){//A窗口奇编号,2倍速
				System.out.printf(q1.poll()+" "+q1.poll()+" ");//A窗口输出
				if(q2.size()>=1)//B窗口偶编号,单倍速
					System.out.printf(q2.poll()+" ");//B窗口输出
			}
			if(No[i]%2==1)
				q1.add(No[i]);//奇编号加入q1队列
			else
				q2.add(No[i]);//偶编号加入q2队列
		}
                while(q1.size()>1)
			System.out.printf(q1.poll()+" ");
		if(q1.size()==1)//控制输出最后不含空格
			System.out.printf(q1.poll()+"");
		while(q2.size()>1)
			System.out.printf(q2.poll()+" ");
		if(q2.size()==1)//控制输出最后不含空格
			System.out.printf(q2.poll()+"");

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

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

	public static void main(String[] args) {
		Set<String> strSet = new TreeSet<String>();//TreeSet本身实现有序
		Scanner in = new Scanner(System.in);
		int m = 10;
		while (in.hasNext()) {
			String str = in.next();
			if(str.equals("!!!!!"))//结束输入
				break;
			else if (!strSet.contains(str))
				strSet.add(str);//添加到strSet
		}
		System.out.println(strSet.size());//打印strSet大小,即文字中的单词数量
		if (strSet.size() <= 10)//打印格式,单词数小于等于10,全部打印
			for (String s : strSet) {
				System.out.println(s);
			}
		else//单词数大于10,按单词的字母顺序排序后输出前十
			for (String s : strSet) {
				if (m-- <= 0)
					break;
				System.out.println(s);
			}
		in.close();

	}

5.1 实验总结

  • Set集不含重复对象
  • Set无序,但实现类TreeSet按特定方式排序

6. 选做:加分考察-统计文字中的单词数量并按出现次数排序

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

6.1 伪代码

		Map<String, Integer> cm = new TreeMap<String, Integer>();//因为键对象不可重复,值对象可重复,让单词对应键String,除此案次数对应值Integer
		while (in.hasNext()) {
			String str = in.next();
			if (str.equals("!!!!!"))//结束输入
				break;
			else if (!cm.containsKey(str))//判断键对象是否存在
				cm.put(str, 1);//新键值对
			else {//已存在键对象
				int n = (int) cm.get(str);//<k,v>获取v值
				cm.put(str, n + 1);//v值+1,存入TreeMap
			}
		}
		List<Map.Entry<String, Integer>> arrayList = new ArrayList<Map.Entry<String, Integer>>(cm.entrySet());//创建一个列表接收键值对
		Collections.sort(arrayList, new Comparator<Map.Entry<String, Integer>>() {//匿名内部类,比较
			public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
				return ((Integer) o2.getValue()) - ((Integer) o1.getValue());
			}
		});
		int n=10;
		for (Map.Entry<String, Integer> entry : arrayList) {//控制输出
			if(n--==0)
				break;
			String key = entry.getKey();
			Integer value = entry.getValue();
			System.out.println(key + "=" + value);
		}

6.2 实验总结

  • 用Map的put(k,v)方法向集合中加入新元素
  • 用get方法检索键对象映射的值对象
  • TreeMap是按键对象排序的,如果要按值对象排序则要写一个比较方法

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

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

7.2 使用集合类改进大作业

	LinkedList<Shopcart> list;
	public Shopcart Add(Product goods,double sum){
		Shopcart sc=new Shopcart(goods);
		sc.sum=sum;
		list.add(sc);
		return sc;
	}

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

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

3.1. 码云代码提交记录

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

3.2. PTA实验

编程(5-1, 5-2, 5-3(选做), 5-6)

posted on 2017-04-08 17:45  七秒の鱼  阅读(230)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3