• subList 死循环


    问题描述:

    如下代码会造成死循环

            int startI = 1;
            int endI = startI + 1;
            List<Integer> result = integerList.subList(0, 1);
            while (startI < integerList.size()) {
                List<Integer> subList = integerList.subList(startI, endI);
                result.addAll(subList);
                startI = endI;
                endI = startI + 1;
            }

    原因:

    subList函数没有创建新的对象,而是记录坐标,使用了原本的列表对象。

    Java Doc 如下:

        /**
         * Returns a view of the portion of this list between the specified
         * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.  (If
         * <tt>fromIndex</tt> and <tt>toIndex</tt> are equal, the returned list is
         * empty.)  The returned list is backed by this list, so non-structural
         * changes in the returned list are reflected in this list, and vice-versa.
         * The returned list supports all of the optional list operations supported
         * by this list.<p>
         *
         * This method eliminates the need for explicit range operations (of
         * the sort that commonly exist for arrays).  Any operation that expects
         * a list can be used as a range operation by passing a subList view
         * instead of a whole list.  For example, the following idiom
         * removes a range of elements from a list:
         * <pre>{@code
         *      list.subList(from, to).clear();
         * }</pre>
         * Similar idioms may be constructed for <tt>indexOf</tt> and
         * <tt>lastIndexOf</tt>, and all of the algorithms in the
         * <tt>Collections</tt> class can be applied to a subList.<p>
         *
         * The semantics of the list returned by this method become undefined if
         * the backing list (i.e., this list) is <i>structurally modified</i> in
         * any way other than via the returned list.  (Structural modifications are
         * those that change the size of this list, or otherwise perturb it in such
         * a fashion that iterations in progress may yield incorrect results.)
         *
         * @param fromIndex low endpoint (inclusive) of the subList
         * @param toIndex high endpoint (exclusive) of the subList
         * @return a view of the specified range within this list
         * @throws IndexOutOfBoundsException for an illegal endpoint index value
         *         (<tt>fromIndex &lt; 0 || toIndex &gt; size ||
         *         fromIndex &gt; toIndex</tt>)
         */
        List<E> subList(int fromIndex, int toIndex);

    解决方式:

    写了一个比较糙的方法,如下:

        private <T> List<T> copySubList(List<T> origin, int startI, int endI) {
            List<T> subList = origin.subList(startI, endI);
            List<T> result = new ArrayList<>(subList.size());
            result.addAll(subList);
            return result;
        }

    反思:

    假设有程序员小明需要开发以上逻辑,在没有人事先提醒的情况下,小明写出死循环的概率有多大?小明自己预感到可能有问题的概率有多大?

    应该有人事先提醒小明吗,应该提醒每一个“小明”吗?

    应该修改subList的函数签名吗?

  • 相关阅读:
    一个java程序员自学IOS开发之路(十三)
    一个java程序员自学IOS开发之路(十二)
    一个java程序员自学IOS开发之路(十一)
    Swift学习笔记(六)
    一个java程序员自学IOS开发之路(十)
    Swift学习笔记(五)
    ubuntu服务器环境配置参考
    ubuntu添加新用户并添加管理员权限
    java GUI Graphics2D 绘图
    java链接数据库--Mysql
  • 原文地址:https://www.cnblogs.com/afraidToForget/p/13471156.html
Copyright © 2020-2023  润新知