zoukankan      html  css  js  c++  java
  • 201521123055 《Java程序设计》第7周学习总结

    1. 本章学习总结

    2. 书面作业

    1.ArrayList代码分析

    1.1 解释ArrayList的contains源代码

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

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

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

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

    答:

    (1) 先贴上contains源码及自带注释

     /**
     * Returns <tt>true</tt> if this list contains the specified element.
     * More formally, returns <tt>true</tt> if and only if this list contains
     * at least one element <tt>e</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
     *
     * @param o element whose presence in this list is to be tested
     * @return <tt>true</tt> if this list contains the specified element
     */
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
    
    /**
     * Returns the index of the first occurrence of the specified element
     * in this list, or -1 if this list does not contain the element.
     * More formally, returns the lowest index <tt>i</tt> such that
     * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
     * or -1 if there is no such index.
     */
    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;
    }
    

    其作用是验证该ArrayList中是否包含某个对象,从源代码来看,其默认使用for循环Object类下的equals方法进行比较,很明显在实际操作时我们需要在个人类中重写equals方法,否则只会比较其地址值,必定返回false。

    (2)贴上源码

       E remove(int index);
    

    根据下标删除对象,由于ArrayList是List的一个实现类,并且还继承了AbstractList类。贴上AbstractList类中和List接口中的remove描述

    public E remove(int index) {
        throw new UnsupportedOperationException();
    }
    
    
    /**
     * Removes the element at the specified position in this list (optional
     * operation).  Shifts any subsequent elements to the left (subtracts one
     * from their indices).  Returns the element that was removed from the
     * list.
     *
     * @param index the index of the element to be removed
     * @return the element previously at the specified position
     * @throws UnsupportedOperationException if the <tt>remove</tt> operation
     *         is not supported by this list
     * @throws IndexOutOfBoundsException if the index is out of range
     *         (<tt>index &lt; 0 || index &gt;= size()</tt>)
     */
    E remove(int index);
    

    暂时不关注抛出的异常,另外还有remove(Object o)方法,实现最后也是转到remove(int index)上来。

    (3)

        ArrayList arr=new ArrayList();
        arr.add(123);
        arr.add("123");
    

    运行通过,在技术层面来说可以实现。但是之前也说了,如果是一些基本类型进行增删查改不难,但假如里面存放的是各种各样用户自定义类,那么我们就必须重写equals方法,类的种类如此之多,怎么重写呢?因此ArrayList还是要考虑数据类型的。

    (4)

    贴上源码

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

    继续看ensureCapacityInternal方法描述

    private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }
    
        ensureExplicitCapacity(minCapacity);
    }
    

    DEFAULTCAPACITY_EMPTY_ELEMENTDATA是一个空数组,用于判断此时ArrayList是否为空。顺便一提,数组的默认长度DEFAULT_CAPACITY值为10。

    继续看ensureExplicitCapacity方法描述

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;
    
        // overflow-conscious code
        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);
        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);
    }
    

    简单说一下,将原有的数组扩容为1.5倍长度的数组(使用移位运算<<),将原有的数组元素赋值到新数组中。

    (5)

    贴上rangeCheck描述

    /**
     * Checks if the given index is in range.  If not, throws an appropriate
     * runtime exception.  This method does *not* check if the index is
     * negative: It is always used immediately prior to an array access,
     * which throws an ArrayIndexOutOfBoundsException if index is negative.
     */
    

    此方法不检查是否为负数,因为声明为private,内部调用的话传入的肯定是正值,如果声明为public,那么可从外部传入负值,那么抛出了一个数组下标越界的异常,不符合逻辑。

    2.HashSet原理

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

    答:

    (1)贴上HashSet.add方法描述

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
    

    说明数据在HashSet内是以基于哈希表的map形式存储的,继续看put方法的描述

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
    

    说明查找是基于键值对的形式进行的。

    3.ArrayListIntegerStack

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

    3.2 简单描述接口的好处.

    答:

    (1)根本区别就是一个内部使用数组实现,一个内部使用ArrayList实现,数组的话增删查改都要自己编写方法,ArrayList可以调用已有方法进行操作。

    (2)接口中规定了实现类必须去实现的各种方法,思路清晰,也规范了编程流程。

    Q4.Stack and Queue

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

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

    答:

    (1)

    import java.util.ArrayList;
    import java.util.Scanner;
    
    /**
     * Created by Administrator on 2017/4/8.
     */
    public class Main201521123055 {
        public static void main(String[] args) {
    
            Scanner sc=new Scanner(System.in);
            String s=sc.nextLine();
            stackString str=new stackString(s);
            for(int i=0;i<str.size();i++)
            {
                if(s.charAt(i)!=str.pop())
                {
                    System.out.println("不是回文字符串");
                    return;
                }
            }
    
            System.out.println("是回文字符串");
    
    
        }
    }
    
    
    class stackString{
        ArrayList<Character> arr=new ArrayList<Character>();
    
        stackString(String s)
        {
            for(int i=0;i<s.length();i++)
                arr.add(s.charAt(i));
        }
        public void push(Character c)
        {
            arr.add(c);
        }
    
        public Character pop() {
            if(arr.size()==0)return null;
            Character c = arr.get(arr.size() - 1);
            arr.remove(arr.size() - 1);
            return c;
        }
    
        public int size()
        {
            return arr.size();
        }
    
    }
    

    (2)我使用了ArrayList进行模拟,跟队列来说效果上差不太多。

        ArrayList<Integer> arr1=new ArrayList<Integer>();
        ArrayList<Integer> arr2=new ArrayList<Integer>();
    
        int n=sc.nextInt();
        for(int i=0;i<n;i++)
        {
            int m=sc.nextInt();
    
            if(m%2==1)arr1.add(m);
            else arr2.add(m);
        }
        Collections.sort(arr1);
        Collections.sort(arr2);
    

    排序后按照规则输出。

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

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

    5.1 实验总结

    (1)

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

    此题代码量不大故全部贴上来。

    (2)这题关键就是使用了Set的自然排序实现类TreeSet,此类可以对添加的对象进行默认排序。

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

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

    6.1 伪代码

    6.2 实验总结

    (1)伪代码?不存在的。直接上源代码

    public class Main
    {
        public static void main(String[] args) {
            Scanner sc=new Scanner(System.in);
            Map<String,Integer> dic=new HashMap<String,Integer>();
            String str=null;
            while(true)
            {
                str=sc.next();
                if(str.equals("!!!!!"))break;
    
                if(dic.containsKey(str))
                {
                    Integer i=dic.get(str);
                    i++;
                    dic.put(str,i);
                }
                else
                {
                    dic.put(str,1);
                }
            }
    
    
    
            Map<String, Integer> sortdic = sortMapByValue(dic);
            System.out.println(sortdic.size());
    
            int i=0;
            for (Map.Entry<String, Integer> entry : sortdic.entrySet()) {
                if(i==10||i>=sortdic.size())break;
                System.out.println(entry.getKey() + '=' + entry.getValue());
                i++;
            }
        }
    
    
    
        public static Map<String, Integer> sortMapByValue(Map<String, Integer> oriMap) {
            if (oriMap == null || oriMap.isEmpty()) {
                return null;
            }
            Map<String, Integer> sortedMap = new LinkedHashMap<String, Integer>();
            List<Map.Entry<String, Integer>> entryList = new ArrayList<Map.Entry<String, Integer>>(
                    oriMap.entrySet());
            Collections.sort(entryList, new MapComparatorByValue());
    
            Iterator<Map.Entry<String, Integer>> iter = entryList.iterator();
            Map.Entry<String, Integer> tmpEntry = null;
            while (iter.hasNext()) {
                tmpEntry = iter.next();
                sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());
            }
            return sortedMap;
        }
    }
    
    class MapComparatorByValue implements Comparator
    {
        @Override
        public int compare(Object o1,Object o2)
        {
            Map.Entry<String,Integer> m1=(Map.Entry<String,Integer>)o1;
            Map.Entry<String,Integer> m2=(Map.Entry<String,Integer>)o2;
            if(m2.getValue()==m1.getValue())
            {
                return m1.getKey().compareTo(m2.getKey());
            }
            else return m2.getValue()-m1.getValue();
    
        }
    }
    

    (2)这道题重点是使用了map集合储存数据,并且还需要按值排序,因此要自定义比较器进行排序。我个人觉得最麻烦的就是map转为list来进行排序,为此看了不少资料才弄明白。

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

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

    7.2 使用集合类改进大作业

    这里说明一下,因为之前用的就是集合类来写的,所以改进的话也就是在界面上做优化,这两周好好看下图形化处理方面的资料在做改进。这周暂停进度。

    3.1 码云提交记录

    因个人资料的集中管理,故把作业也扔到GitHub上面提交。(GitHub还有桌面客户端方便管理,何乐不为呢)

    Github地址

  • 相关阅读:
    【codecombat】 试玩全攻略 第二章 边远地区的森林 一步错
    【codecombat】 试玩全攻略 第十八关 最后的kithman族
    【codecombat】 试玩全攻略 第二章 边远地区的森林 woodlang cubbies
    【codecombat】 试玩全攻略 第二章 边远地区的森林 羊肠小道
    【codecombat】 试玩全攻略 第十七关 混乱的梦境
    【codecombat】 试玩全攻略 第二章 边远地区的森林 林中的死亡回避
    【codecombat】 试玩全攻略 特别关:kithguard斗殴
    【codecombat】 试玩全攻略 第二章 边远地区的森林 森林保卫战
    【codecombat】 试玩全攻略 第二章 边远地区的森林
    实验3 类和对象||
  • 原文地址:https://www.cnblogs.com/wkfg/p/6682112.html
Copyright © 2011-2022 走看看