zoukankan      html  css  js  c++  java
  • 需要注意的subList方法!和substring是不一样的!从源码解释他们的不同。

    很多时候我们截取字符串用的是substring方法,很自然用着,但是对于列表的截取时很多时候就用得很少,但是其实他们是很不一样的,具体哪里不一样呢?

    package main;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @author XX
     *
     */
    public class Test {
    
        public static void main(String[] args) {
            //先来一个字符串
            String abcd = "abcd";
            //删除字符串前面两个字符
            String cd = abcd.substring(2);
            //true
            System.out.println(cd.equals(cd));
            //false
            System.out.println(abcd.equals(cd));
            
            //下面的源码很容易解释这个问题,造成这个结果的原因是,生成了一个新的字符串,所以不一样,很正常也容易理解
            
            /*public String substring(int beginIndex) {
                if (beginIndex < 0) {
                  throw new StringIndexOutOfBoundsException(beginIndex);
                }
                int subLen = value.length - beginIndex;
                if (subLen < 0) {
                   throw new StringIndexOutOfBoundsException(subLen);
                }
                    return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
            }*/
            
            
            List<Integer> list = new ArrayList<Integer>();
            list.add(3);
            list.add(2);
            list.add(2);
            list.add(4);
            list.add(1);
            list.add(5);
            
            List<Integer> list2  = list.subList(0, list.size());
            list2.add(2);
            //true?为什么list截取之后再加元素还是true呢?
            System.out.println(list.equals(list2));
            //如果不明白的话,打印个原来列表的size就明白了,结果是7,原来只有6个元素哦
            System.out.println(list.size());
            
            
            
            //然后我们再看看源码是怎么样的
            /*
             * public List<E> subList(int fromIndex, int toIndex) 
             * {
             *     subListRangeCheck(fromIndex, toIndex, size);
             *    return new SubList(this, 0, fromIndex, toIndex);
             * }
             * 
             * 首先是进入这个方法,是List中的subList中ArrayList实现的那个方法
             * subListRangeCheck这个我们不管,看命名就知道是判断能不能sub
             * 直接进下一个方法,别看到new就着急,往里面看看
             * private class SubList extends AbstractList<E> implements RandomAccess {
                    private final AbstractList<E> parent;
                    private final int parentOffset;
                    private final int offset;
                    int size;
            
                    SubList(AbstractList<E> parent,
                            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;
                    }
            
                    public E set(int index, E e) {
                        rangeCheck(index);
                        checkForComodification();
                        E oldValue = ArrayList.this.elementData(offset + index);
                        ArrayList.this.elementData[offset + index] = e;
                        return oldValue;
                    }
            
                    public E get(int index) {
                        rangeCheck(index);
                        checkForComodification();
                        return ArrayList.this.elementData(offset + index);
                    }
            
                    public int size() {
                        checkForComodification();
                        return this.size;
                    }
                    
                    
                    。。。。。
                    后面的方法省略了
                    
                    这里我们就可以看到,其实在这里的操作,都是this. = 
                    这就表示所有的操作都是在原来的列表上面操作的。
                    
                    简单的说,subList方法只是返回了一个原来列表的视图而已
             * 
             * */
            
            
            //利用这个性质可以实现删除列表中任何位置的连续的一段值,代码如下
            list.subList(0, 2).clear();
            //执行上面这句之后,列表就变成了[2, 4, 1, 5, 2],删除了前面两个数,列表的大小也变成了5
            System.out.println(list.size());
            
            //需要提醒的是,一旦用过subList方法之后,就不要对原来的列表进行任何操作了,
            //否则在对新列表操作时就会出现并发修改异常,这也和这个性质有关
            
        }
    }
  • 相关阅读:
    ElasticSearch Java API 增删改查操作
    ElasticSearch Java API连接报错NoNodeAvailableException解决方案
    Elasticsearch 使用Kibana实现基本的增删改查+mget批量查询+bulk批量操作
    Elasticsearch CentOS6.5下安装ElasticSearch6.2.4+elasticsearch-head+Kibana
    Elasticsearch 核心概念:NRT+索引+分片+副本
    Solr solrj4与solrj-7.7.2操作solrcloud
    Solr Centos6.5下搭建solr-7.7.2集群solrcloud+DIH操作
    分层图【p2939】[USACO09FEB]改造路Revamping Trails
    NOIP2018提高组模拟题(二)
    树链剖分【p3178】[HAOI2015]树上操作
  • 原文地址:https://www.cnblogs.com/linkstar/p/5710116.html
Copyright © 2011-2022 走看看