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地址

  • 相关阅读:
    utools很方便的软件,你的生产力工具集
    uos、deepin安装nfs、查看nfs日志路径
    91--spring cloud (luceneAPI-solr)
    91--spring cloud (Config配置中心--客户端)
    90--spring cloud (Config配置中心)
    90--IDEA整合Git
    解决 IDEA控制台中不能输入数据
    89--spring cloud (zuul-API网关/与feign的比较)
    88--spring cloud (Springboot 整合RabbitMQ)
    88--spring cloud (Turbine聚合监控)
  • 原文地址:https://www.cnblogs.com/wkfg/p/6682112.html
Copyright © 2011-2022 走看看