java里的List<T>接口里的subList方法,API没看懂

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java里的List<T>接口里的subList方法,API没看懂相关的知识,希望对你有一定的参考价值。

第一点,什么是视图?这个词是翻译者发明出来的吗?是不是说子列表和源列表共用一个引用数组,只是子列表的使用权限限制在了截取指定的那两个索引之间?第二点,非结构性更改,clear是结构性更改吗?如api上写的,调用subList(a,b).clear()能清除a到b之前的元素,实际上它也是把子列表清空了,这样用是完全可以的,但为什么对原列表clear操作就会报错?第三点,其实List的实现方式我也不懂,是不是就是我第一点说的,内部维护了一个引用数组,分别指向存储的对象?删除元素就是删除引用,然后等gc回收?啊啊啊,今天真的是被集合里的一些东西搞晕了,知道怎么用,但不知道它到底怎么实现的,不痛快啊,泛型的类型擦除也头疼,他俩凑一块更头疼了....

1,并不是发明出来的,原文就是view,就是视图的意思。
视图的概念借用了数据库的view概念。sablist返回的list和原来的list,后面的数据是同一份,所以对任何item本身的修改,会反映到另一个list。
2,因为sublist知道使用了哪个fullList,当然能够正确处理clear;反过来却不然,所以,对fullList的clear,会造成未定义的结果。

3,如果是arrayList,是你说的那样,remove的话,会把后面的数据向前串一个,然后等着回收呗;如果是link list,就是链表结构了。追问

13懂了,2还是有点2,看来还是我太二了。。是不是说sublist的一系列操作都会得到很明确的结果,而改变fulllist结构带来的后果对于sublist却是未知的,后者的这种改变会完全破坏sublist的意义?

追答

你子列表不是调用subList方法取来的么,这时候,你是能知道full列表的情况的,所以实现的时候,比如你remove一个元素,告诉fullList也remove就行了;
但是反过来就不行了,fullList哪知道有几个子列表在盯着自己啊,不知道,所以一删除就完蛋了,子列表不知道这个情况啊,不知道实际上自己的长度少了一个。。。
所以,只能你自己保证,调用subList操作的期间,不能动fullList了。

追问

大概就这样了吧,你是第一个回答的,采纳了

参考技术A 视图这个概念,怎么讲呢,它是对原始数据的一种映射,至于怎么映射,看具体实现。
比如说[1, 2, 3]这个数组,按某种映射成['a', 'b', 'c'],那么后者也是前者的视图。

具体到你这个问题,你的说法基本正确,反正对视图的修改会映射回原始数据,对原始数据的修改也会反映在视图上,你知道这一点就行了。

第二点,clear()当然是结构性修改。对原列表clear()会报错?不是很懂你意思,上代码。

第三点,List没有实现,它只是一个接口。具体的实现如ArrayList、LinkedList等的结构都是不一样的。删除元素就是删除引用,这个没有错。追问

可以了可以了,辛苦,只是你晚了一步😁

Java学习之List接口

List接口

  List接口的定义如下:

public interface List<E>extends Collection<E>

  可以发现List接口时Collection接口的子类,List接口大量的扩充了Collection接口的操作,List接口里的内容是允许重复的。

List接口常用方法

  一句话概括这些方法的功能:就是为了实现增删减查的功能。

  有如下的方法:

void add(int index,E element)
//在列表的指定位置插入指定元素(可选操作)。将当前处于该位置的元素(如果有的话)和所有后续元素向右移动(在其索引中加 1)。 
boolean addAll(int index, Collection<? extends E> c)
//将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
E get(int index)    //返回列表中指定位置的元素。
int indexOf(Object o)
//返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1
E set(int index,E element)
//用指定元素替换列表中指定位置的元素(可选操作)。
boolean remove(Object o)
//从此列表中移除第一次出现的指定元素(如果存在)(可选操作)。如果列表不包含元素,则不更改列表。

  当然除了以上这些,还有其他的方法。

List接口的子类—ArrayList(常用)

  ArrayList的定义如下:

public class ArrayList<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, Serializable

  ArrayList是List接口的子类,那么如果想使用List接口,就必须通过对象的多态性来实例化List接口。下面通过实例了解ArrayList。

  实例一:指定位置添加数据

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> lists=new ArrayList<String>();
        lists.add("Hello");    //加入内容
        lists.add(0,"world");
        System.out.println(lists);
    }
}

  运行结果如下:

[world, Hello]

  实例二:指定位置添加内容

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> lists=new ArrayList<String>();
        List<String> lists1=new ArrayList<String>();
        lists.add("Hello");
        lists.add("world");
        System.out.println(lists);
        lists1.add("This");
        lists1.add("is");
        lists.addAll(0,lists1);  //在指定位置添加一组内容
        System.out.println(lists);
    }
}

  运行结果如下:

[Hello, world]
[This, is, Hello, world]

  实例三:删除内容(可以使用两种方式)

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> lists=new ArrayList<String>();
        lists.add("输出:");
        lists.add("Hello");
        lists.add("world");
        System.out.println(lists);
        lists.remove(0); //通过编号删除内容
        System.out.println(lists);
        lists.remove("Hello");  //通过内容来删除内容
        System.out.println(lists);
    }
}

  运行结果如下:

[输出:, Hello, world]
[Hello, world]
[world]

  通过以上程序我们发现内容前后都有‘[]‘,还存在‘,‘,那么如何去除他们呢?

  实例四:依次输出内容

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> lists=new ArrayList<String>();
        lists.add("输出:");
        lists.add("Hello");
        lists.add("world");
        for(int i=0;i<lists.size();i++){  //size()方法取得集合中内容的个数
            System.out.println(lists.get(i));  //get()方法取得其中的内容
        }
    }
}

  运行结果如下:

输出:
Hello
world

  此输出方式(根据所有取出内容)是List接口独有的,其他接口时没有的。这也是为什么List接口里的内容可以重复的原因。

  实例四

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest {
    public static void main(String[] args) {
        List<String> lists=new ArrayList<String>();
        System.out.println("判断集合是否为空:"+lists.isEmpty());
        lists.add("输出:");
        lists.add("Hello");
        lists.add("world");
        System.out.println("Hello所在位置是:"+lists.indexOf("Hello"));
        System.out.println("是否存在world:"+lists.contains("world"));
    }
}

  输出结果如下:

判断集合是否为空:true
Hello所在位置是:1
是否存在world:true

总结:

  List中允许重复元素

以上是关于java里的List<T>接口里的subList方法,API没看懂的主要内容,如果未能解决你的问题,请参考以下文章

java里的JSONObject作用是啥?啥时候用?

Java里的泛型加通配符的用法

java把一个list里的数据转移到另外一个list

Java学习之List接口

java怎样取list里的数据

Java如何去掉List<实体> 实体里的重复数据