再说Java调集,subList之于ArrayList /A8站源码交易平台

摘要:关于SubList的其他办法,其实和add原理相同,不论是set(int index, E e),get(int index),addAll(Collection c),remove(int index),都是先判别当时传入的方位索引是否正确(如是否大于size,小于0等),再依据规矩计算出原调集中的方位下标,终究完成对调集的操作。

先看一段代码

A8站源码交易平台


public static void testSubList() {
    ListstringList = new ArrayList<>();
    stringList.add("牛魔王");
    stringList.add("蛟魔王");
    stringList.add("鹏魔王");
    stringList.add("狮驼王");
    stringList.add("猕猴王");
    stringList.add("禺贼王");
    stringList.add("美猴王");

    Listsubstrings = stringList.subList(3,5);
    System.out.println(substrings.toString());
    System.out.println(substrings.size());
    substrings.set(1, "猪八戒");
    System.out.println(substrings.toString());
    System.out.println(stringList.toString());
}



看看履行成果怎么样?

[狮驼王, 猕猴王]
2
[狮驼王, 猪八戒]
[牛魔王, 蛟魔王, 鹏魔王, 狮驼王, 猪八戒, 禺贼王, 美猴王]



第一和第二的履行成果,十分简单了解,subList()办法效果便是截取调集stringList中一个规模内的元素。

第三和第四的履行成果都值得分析了,首要截取的字符串调集值为 [狮驼王, 猕猴王] ,但由于猕猴王在大雷音寺被美猴王打死了,咱们用猪八戒来替代猕猴王;

因而咱们经过substrings.set(1, “猪八戒”),将这个调集中第二个方位的值**“猕猴王”设置为“猪八戒”,终究打印出来的成果也正是咱们所预期的;但一起咱们打印原调集stringList,发现其间的“猕猴王”也变成了“猪八戒”**。这就比较奇怪了,两个问题:

1.咱们操作的是截取后的调集,为什么原调集会变?

2.咱们设置截取后某个方位(如第2个方位)的值,原调集改动的却不是对应方位的值?A8站源码交易平台

一. subList原理初探         
接下来咱们带着问题寻觅答案,咱们看一下subList()的源码

/**
 * Returns a view of the portion of this list between the specified
 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.  (If 
 * {@code fromIndex} and {@code toIndex} 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.
 *
 *

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:
 *

 *      list.subList(from, to).clear();

 *


 * Similar idioms may be constructed for {@link #indexOf(Object)} and
 * {@link #lastIndexOf(Object)}, and all of the algorithms in the
 * {@link Collections} class can be applied to a subList.
 *
 *

The semantics of the list returned by this method become undefined if
 * the backing list (i.e., this list) is structurally modified 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.)
 *
 * @throws IndexOutOfBoundsException {@inheritDoc}
 * @throws IllegalArgumentException {@inheritDoc}
 */
public ListsubList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}




看注释,大概有以下几个意思

回来的是原调集在fromIndex和toIndex之间的元素的视图,尽管为视图,但支撑调集的一切办法;
当fromIndex和toIndex相一起,回来空的视图;
任何对截取的视图的操作都会被原调集所替代;
看注释仅能知道咱们比如终究的运转成果是正常的,可是对原理也还并不是特别清楚。咱们持续看源码。A8站源码交易平台

首要咱们在比如中调用subList(3, 5)时,是new了一个SubList,这个SubList是ArrayList内部类,承继了AbstractList

private class SubList extends AbstractListimplements RandomAccess {
    private final AbstractListparent;
    private final int parentOffset;
    private final int offset;
    int size;

    SubList(AbstractListparent, int offset, int fromIndex, int toIndex) {
        this.parent = parent;
        this.parentOffset = fromIndex;
        this.offset = offset + fromIndex;
        this.size = toIndex - fromIndex;
        this.modCount = ArrayList.this.modCount;
    }
}




从这个内部类的源码中,咱们能够看到:

SubList并没有像ArrayList相同界说Object[]来寄存数据,而界说了一个变量parent来保存传递的原调集;
界说了一个offset用于保存进行偏移量,当对SubList修改时,就能够经过偏移量找到parent中对应的方位;
界说了size用来表明咱们在parent调集中可见规模是多少;

1.png


有了上面的阐明,其实SubList的原理现已很明晰了,接下来,咱们用SubList中常用的办法来印证一下。

二. add(E e)办法
substrings.add("九头蛇");
System.out.println(substrings.toString());
System.out.println(stringList.toString());



接着上面的比如,在substrings中增加“九头蛇”,依照规矩,add()办法增加元素会在调集的终究,也便是说substrings的第3个方位(下标为2),对应parent原调集的方位下标便是2+3=5,会在stringList第六个方位刺进“九头蛇”。看一下输出的成果

[狮驼王, 猪八戒, 九头蛇]
[牛魔王, 蛟魔王, 鹏魔王, 狮驼王, 猪八戒, 九头蛇, 禺贼王, 美猴王]

能够看到成果确实如此,那么咱们在看一下add(E e),在SubList这个内部类里边并没有发现该办法,因而我去父类中找。

在AbstractList中找到了

public boolean add(E e) {
    add(size(), e);
    return true;
}



接下来,咱们在SubList中找到了完成办法

public void add(int index, E e) {
    rangeCheckForAdd(index);
    checkForComodification();
    parent.add(parentOffset + index, e);
    this.modCount = parent.modCount;
    this.size++;
}



很明显,源代码和咱们开端的分析是共同的,当然在增加之间需求进行空间容量判别,是否足以增加新的元素,扩容规矩,咱们上一章现已讲过。

三. 其他办法
关于SubList的其他办法,其实和add原理相同,不论是set(int index, E e),get(int index),addAll(Collection c),remove(int index),都是先判别当时传入的方位索引是否正确(如是否大于size,小于0等),再依据规矩计算出原调集中的方位下标,终究完成对调集的操作。A8站源码交易平台

四. 总结
本文续接上一章ArrayList原理及运用,对ArrayList中的常用办法subList进行了分析,从源码的视点对经过subList办法得到的调集和原调集有何联系,有何不同点,然后防止工作中遇到各种坑


A8站源码交易平台


  • 全部评论(0)
最新发布的资讯信息
【A8站-免费源码分享|直播源码】直播系统源码开发:关于安卓开发工具和obs直播推流(2020-10-30 09:41)
【计算机/互联网|】【独家修复】用户定制版短视频点赞系统,支持抖音+快手+刷宝+微视等所有主流短视频评论系统源码(2020-10-26 16:34)
【技术宅-为技术而疯|网站架设教程】【独家首发】最新更新已对接短信2020全新抖音快手点赞任务系统霸屏天下小红书头条威客兼职完整搭建架设视频教程(2020-10-25 13:56)
【技术宅-为技术而疯|网站架设教程】最新可用个人发卡网系统源码完整搭建架设视频教程(2020-10-25 10:53)
【技术宅-为技术而疯|网站架设教程】独家更新全新V10抢单系统唯品会京东淘宝自动抢单区块系统源码全开源抢单收单接单返利+搭建架设完整视频教程(2020-10-25 10:52)
【计算机/互联网|】柔丫纸尿裤云仓系统源码部署(2020-10-15 18:13)
【计算机/互联网|】侏罗纪软件模式定制开发(2020-10-14 15:33)
【计算机/互联网|】S2b2C供应商系统 营销闭环(2020-10-10 17:46)
【计算机/互联网|程序设计开发】盛都汇系统奖励机制(2020-10-10 17:20)
【A8站-免费源码分享|网站源码】积分商城系统APP开发(2020-09-23 14:56)
联系我们
Q Q:3101359898 点击直接对话
电话:18580901894
邮箱:admin#a8zhan.com
时间:09:00 - 24:00
手机二维码 访问手机版
返回顶部