• 201521123042《Java程序设计》 第7周学习总结


    1. 本周学习总结

    网上看了很多资料,发现这一张图总结的还不错就引用过来了。但是最上面的Map和Collection之间的关系应该是依赖,不是Produces。

    ①概述:Java集合框架主要包括两种类型的容器.一种是Collectio),存储一个元素集合,另一种是Map,存储键/值对映射。。Collection接口又有3种子类型,List、Set和Queue,再下面是一些抽象类,最后是具体实现类,常用的有ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap等等.

    ②collection接口:AbstractCollection是提供Collection部分实现的抽象类。有几个比较常用的方法,比如方法:

    • add()添加一个元素到集合中。
    • addAll()将指定集合中的所有元素添加到集合中。
    • contains()方法检测集合中是否包含指定的元素。
    • toArray()方法返回一个表示集合的数组。

    ③List接口扩展自Collection,它可以定义一个允许重复的有序集合。Set接口扩展自Collection,它与List的不同之处在于,规定Set的实例不包含重复的元素。主要是散列集HashSet和树形集TreeSet。Queue接口扩展自Collection,并提供插入、提取、检验等操作。poll()与remove()方法都是移除队列头部的元素,两者的区别在于如果队列为空,那么poll()返回的是null,而remove()会抛出一个异常。

    2. 书面作业

    • Q1.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);
             }
      

      该代码表示的是如果o为null,那么就去找elementData[] 是否有为null的对象,有则返回下标没有则返回-1。
      如果o不为null,就通过equals去比较elementData[] 中是否有与o相同的对象,有则返回下标没有则返回-1。由以上总结我们可知如果对象不为null的话,最终是调用的Object类的equals()方法,来比较两个对象的引用是否相同,在新建类里面我们往往需要重写equals()方法。比如我们用new关键字创建两次User对象,User user1 = new User(1,"lilei");
      User user2 = new User(1,"yueliming");虽然它们代表同一个人,但是JVM虚拟机在中开辟了堆两个存储空间,user1和user2分别为指向这两个对象的引用,所以我们要在User类中重写equals()方法,user1和user2就会被当做同一个对象处理。

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

        public E remove(int index) {
           rangeCheck(index);  //判断index是否合法
         modCount++;  //remove操作会改变size,所以modCount加1
          E oldValue = elementData(index);  //保存待删除位置的元素
        int numMoved = size - index - 1; 
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,numMoved);
            //如果index不是最后一个元素,则从第index+1到最后一个位置,依次向前移动一个位置
            elementData[--size] = null;     //元素的size减少1,并把原来末尾位置元素的值设置为null
        return oldValue;   //返回位置
        } 
      

      由于删除操作会改变size,所以每次删除都需要把元素向前移动一个位置,然后把原来最后一个位置的元素设置为null,一次删除操作完成

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

      答:不需要考虑元素类型,ArrayList会把所有插入其中的数据当作为object类型来处理

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

      add(E e)方法:

        public boolean add(E e) {
             ensureCapacityInternal(size + 1);//保证数组的容量始终够用
             elementData[size++] = e;  //size是elementData数组中元组的个数,初始为0
            return true;
        }
        private void ensureCapacityInternal(int minCapacity) {
            //如果数组没有元素,给数组一个默认大小,会选择实例化时的值与默认大小中较大值
            if (elementData == EMPTY_ELEMENTDATA) {
                minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
            }
            //保证容量够用
            ensureExplicitCapacity(minCapacity);
        }
        private void ensureExplicitCapacity(int minCapacity) {
            //modCount是数组发生size更改的次数
            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);// 设置新容量是原容量的1.5倍
        if (newCapacity - minCapacity < 0)// 容量不够就直接加到所需容量
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        
        elementData = Arrays.copyOf(elementData, newCapacity); 
        } 
      

      每当执行Add添加元素,都会检查内部数组的容量是否不够了,如果不够了,它就会以当前容量的1.5倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组

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

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

      在ArrayList类用户使用remove()方法的时候,只需要直接使用,不需要知道方法内部具体运行过程。所以用private修饰。

    • Q2.Has方法hSet原理

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

      元素存储位置是由元素的hash码来确定的。HashSet是无序存放元素的。使用HashSet的add()方法加入元素时;

      ①自动调用hashCode()方法

      ②然后根据hashCode()方法的返回值 来决定元素要插入的位置。

      ③如果该位置上已经存在元素了 则会调用该元素equals()方法进行比较。
      ④如果两个元素相等 则丢掉欲插入的元素。

      ⑤如果两个元素不相等 则新元素会被加入到另一个位置(通过冲突检测来决定哪一个位置),这样就消除了重复。

      In all,用hashCode()方法来获得元素的存储位置,用equals()方法来比较在两个元素的位置相同的时候,两个元素是否相等

    • 2.2 选做:尝试分析HashSet源代码后,重新解释1.1

      public HashSet() {
          map = new HashMap<>();
      } 
      HashSet实质上使用HashMap来实现的
      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);
      }
      
    • Q3.ArrayListIntegerStack
      题集jmu-Java-05-集合之5-1 ArrayListIntegerStack

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

      ArrayListrStack

       public ArrayIntegerStack(int max) {
      	 data = new Integer[max];
      	       
      }
      

      ArrayListIntegerStack:

       public ArrayListIntegerStack() {
      		list=new ArrayList<Integer>();
         	       
      	}
      

      ①入栈:ArrayListIntegerStack中使用的是动态数组实现栈,当数组空间被用完可以自动扩容,所以不会出现栈慢的情况,ArrayIntegerStack中使用的是数组实现栈,会出现栈满的情况。

      ②出栈:ArrayIntegerStack在出栈的时候需要移动top指针,ArrayListIntegerStack不需要

    • 3.2 简单描述接口的好处.

      同样只能有一个基类,但可以有多个实现。当实现多个接口时,如果两个接口有同样的方法,那么实现一次就可以了。

    • Q4.Stack and Queue

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

        import java.util.ArrayList;
        import java.util.List;
        import java.util.Scanner;
        interface NewStack{
        
        public String push(String item);
        public String pop();
        }
        class Stack implements NewStack{
        private ArrayList<String> list=new ArrayList<String>(); 
        
        public Stack() {
        	list=new ArrayList<String>();
       	       
        }
        
        public String push(String item) {
        if(item==null) return null;
        list.add(item);
        return item;
        }
        public String pop() {
        	if(list.isEmpty()) return null;
        	return list.remove(list.size()-1);
        }
      
        
        }
        public class Main201521123042 {
      
        public static void main(String[] args) {
        	Scanner input=new Scanner(System.in);
        	NewStack stack = new Stack(); 
        	String message=input.next();
        	int i=0;
        	for( i=0;i<message.length();i++)
             stack.push(String.valueOf(message.charAt(i)));
        	for(i=0;i<message.length();i++)
            {
                if(String.valueOf(message.charAt(i)).equals(stack.pop()))continue;
                else
                {
                    System.out.println("false");
                    break;
                }
            }
            if(i==message.length()) System.out.println("true");
           }
      
        }
      
    • 4.2 题集jmu-Java-05-集合之5-6 银行业务队列简单模拟。(不要出现大段代码)

        for(int i=0;i<n;i++){
        int number = input.nextInt();
        if(number%2!=0) queueA.offer(number+"");
        else queueB.offer(number+"");
        }
      

      偶数放在QueueA中,奇数放在QueueB中

        	for (int i = 0; i < n; i++) {
        	while (!queueA.isEmpty()) {
        		System.out.print(queueA.poll()+" ");
        		while (!queueA.isEmpty()) {
        			System.out.print(queueA.poll()+" ");
        			break;
        		}
        		break;
        	}
        	while (!queueB.isEmpty()) {
        		System.out.print(queueB.poll()+" ");
        		break;
        	
        }
      
    • Q5.统计文字中的单词数量并按单词的字母顺序排序后输出
      题集jmu-Java-05-集合之5-2 统计文字中的单词数量并按单词的字母顺序排序后输出 (不要出现大段代码)

      Set<String>strSet=new TreeSet<String>();
      String x;
      while(true){
      	x=input.next();
      	if(x.equals("!!!!!"))break;
      	strSet.add(x);
      	
      }
      System.out.println(strSet.size());
      Iterator item = strSet.iterator();
      for(int i=0;i<10;i++){
      	System.out.println(item.next());
      }
      

      实验总结:利用TreeSet完成不同单词的存放,并有序排列,再利用Iterator遍历strSet中的对象,输出前十个。

    • Q6.选做:加分考察-统计文字中的单词数量并按出现次数排序
      题集jmu-Java-05-集合之5-3 统计文字中的单词数量并按出现次数排序(不要出现大段代码)

    • 6.1 伪代码

         while(true){
        	if(x.equals("!!!!!"))break;
        		else {
        			if(map.containsKey(x)) map.put(x, map.get(x)+1);
        			else map.put(x, 1); 
        		}
        	}
        List<Entry<String,Integer>> list =new ArrayList<Entry<String,Integer>>(map.entrySet());
      
      
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
        	public int compare(Map.Entry<String, Integer> o1,Map.Entry<String, Integer> o2) {
        		//代码
        })
      
    • 6.2 实验总结

      这道题使用了map,用map.containsKey(x)来判断是否已存在映射,使用collections.sort()对list进行排序

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

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

      与上次作业相比,我们加入了表格,使操作更加方便,界面更加美观,改动如下:

       ![](http://images2015.cnblogs.com/blog/1109769/201704/1109769-20170408195111378-2100961640.png)
      
    郭炜埕 姚佳希
    http://www.cnblogs.com/vicheng/p/6668361.html http://www.cnblogs.com/ballonbaby/p/6682818.html

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

    (不知道为什么码云提交不上去,所以只好拖拽上传文件)

  • 相关阅读:
    超过5名学生的课
    大的国家
    shell启动时读取的配置文件
    shell中的环境变量
    chisel中pviews命令无法使用
    shell script中的$*和$@
    OS X EI Capitan 10.11.4中sudo无法起作用的解决方法
    如何判断CPU的位数
    block中无法使用C数组变量
    布尔代数
  • 原文地址:https://www.cnblogs.com/ballonbaby/p/6682818.html
Copyright © 2020-2023  润新知