List与ArrayList

news2024/11/30 0:46:51

目录

一、List及其使用

        1.1 List的概念

        1.2 常见接口的介绍

        1.3 List的使用

二、线性表和顺序表

        2.1 线性表

        2.2 顺序表

三、ArrayList介绍

四、ArrayList的使用

        4.1 ArrayList构造

        4.2 ArrayList的常用方法

        4.3 ArrayList的遍历

        4.4 ArrayList的扩容机制

五、ArrayList的具体使用

        5.1 简单洗牌算法

        5.2 杨辉三角

六、ArrayList的问题


一、List及其使用

        1.1 List的概念

        在集合框架中,List是一个接口,继承自Collection。
         

        Collection也是一个接口,该接口中规范了后序容器中常用的一些方法:
                

        Iterable也是一个接口,表示实现该接口的类是可以逐个元素进行遍历的:

                 

        从数据结构角度看,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删改查以及变量等操作

        1.2 常见接口的介绍

        List中有许多方法:

        

        虽然方法多,但常用方法如下:

方法解释
boolean add(E e)尾插 e
void add(int index, E element)将 e 插入 index 位置
boolean addAll(Collection<? extends E> c)尾插 c 中的元素
E remove(int index)删除 index 位置元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置的元素
E set(int index, E element)将 index 位置的元素设置为element
void clear()清空
boolean contains(Object o)判断 o 是否包含在线性表中
int indexOf(Object o)返回第一个 o 的下标
int lastIndexOf(Object o)返回最后一个 o 的下标
List<E> subList(int fromIndex, int toIndex)截取部分list

        1.3 List的使用

                List是个接口,并不能直接用来实例化。如果要使用,必须去实例化List的实现类。在集合框架中,ArrayList和LinkedList都实现了List接口

二、线性表和顺序表

        2.1 线性表

        线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种广泛使用的数据结构,常见线性表有:顺序表、链表、栈、队列......        

        2.2 顺序表

        顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储,在数组上完成数据的增删查改。
        模拟实现顺序表中的常用函数

public interface IList {
    //新增元素,默认在数组最后新增
    public void add(int data);
    // 在 pos 位置新增元素
    public void add(int pos, int data);
    // 判定是否包含某个元素
    public boolean contains(int toFind) ;
    // 查找某个元素对应的位置
    public int indexOf(int toFind);
    // 获取 pos 位置的元素
    public int get(int pos);
    // 给 pos 位置的元素设为 value  更新
    public void set(int pos, int value);
    //删除第一次出现的关键字key
    public void remove(int toRemove) ;
    // 获取顺序表长度
    public int size();
    // 清空顺序表
    public void clear() ;
    // 打印顺序表,注意:该方法并不是顺序表中的方法,为了方便看测试结果给出的
    public void display();
    boolean isFull();
    public boolean isEmpty();
}
public class MyArrayList implements IList{
    private  int[] elem;
    private  int usedSize;
    //顺序表默认大小
    private static  int DEFAULT_Size=10;

    public MyArrayList(){
        elem=new int[DEFAULT_Size];
    }
    public  MyArrayList(int capacity){
        elem=new int[capacity];
        DEFAULT_Size=capacity;
    }

    //添加一个数据
    @Override
    public void add(int data) {
        chackCapacity();
        this.elem[usedSize]=data;
        this.usedSize++;
    }
    //检查容量
    private void chackCapacity(){
        if(isFull()){
            elem= Arrays.copyOf(elem,elem.length*2);
        }
    }

    //在pos插入一个数据
    @Override
    public void add(int pos, int data) {
        try {
            chackPosOnAddOrGetOrSet(pos);
        }catch (PosError e){
            e.printStackTrace();
            return;
        }
        chackCapacity();
        for (int i = usedSize; i >pos ; i++) {
            elem[i]=elem[i-1];
        }
        elem[pos]=data;
        usedSize++;
    }
    /*检查pos的合法性*/
    private void chackPosOnAddOrGetOrSet(int pos) throws PosError{
        if(pos<0||pos>=this.usedSize)
            throw new PosError("下标异常"+pos);
    }
    //判断顺序表是否包含toFind
    @Override
    public boolean contains(int toFind) {
        if(isEmpty())
            return false;
        for (int x:elem) {
            if(x==toFind)
                return true;
        }
        return false;
    }
    //获取toFing对应的下标
    @Override
    public int indexOf(int toFind) {
        for (int i = 0; i < this.usedSize; i++) {
            if(elem[i]==toFind)
                return i;
        }
        return -1;
    }
    //获取pos下标对应的元素值
    @Override
    public int get(int pos) {
        if(isEmpty())
            return -1;
        chackPosOnAddOrGetOrSet(pos);
        return this.elem[pos];
    }
    //设置下标为pos的元素值为value
    @Override
    public void set(int pos, int value) {
        chackPosOnAddOrGetOrSet(pos);
        elem[pos]=value;
    }
    //删除toRemove
    @Override
    public void remove(int toRemove) {
        int index=indexOf(toRemove);
        if(index<0){
            System.out.println("要删除的数不存在");
            return;
        }
        for(int i=index;i<this.usedSize-1;i++){
            this.elem[i]=this.elem[i+1];
        }
        this.usedSize--;
    }
    //获取当前顺序表的大小
    @Override
    public int size() {
        return this.usedSize;
    }
    //清空
    @Override
    public void clear() {
        for (int i = 0; i < usedSize; i++) {
            set(i,0);
        }
    }
    /*遍历顺序表当中的元素*/
    @Override
    public void display() {
        if(isEmpty()){
            throw new MyArrayIsEmpty("顺序表是空的");
        }
        for(int i=0;i<elem.length;i++){
            System.out.println(this.elem[i]+" ");
        }
        System.out.println();
    }
    /*判断顺序表是否已满*/
    @Override
    public boolean isFull() {
        /*if(usedSize==DEFAULT_Size)
                return true;
        else
            return false;*/
        return  usedSize==DEFAULT_Size;
    }

    @Override
    public boolean isEmpty() {
        return elem.length==0;
    }
}
public class MyArrayIsEmpty extends RuntimeException{
    public MyArrayIsEmpty(String massage){
        super(massage);
    }
}
public class PosError extends RuntimeException{
    public PosError(String massage){
        super(massage);
    }
}

三、ArrayList介绍

        在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架如下:
        

        ArrayList是以泛型方式实现的,使用时必须要先实例化;ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问;ArrayList实现了Cloneable接口,表明ArrayList是可以clone的;ArrayList实现了Serializable接口,表明ArrayList是支持序列化的;ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList;ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表。

四、ArrayList的使用

        4.1 ArrayList构造

方法解释
ArrayList()无参构造
ArrayList(Collection<? extends E> c)利用其他 Collection 构建 ArrayList
ArrayList(int initialCapacity)指定顺序表初始容量
public static void main(String[] args) {
    //创建一个空列表 ArrayList()  默认size为0
    ArrayList<Integer> list1=new ArrayList<>();

    //创建一个容量为10的列表  ArrayList(int initialCapacity)创建指定容量的列表
    //ArrayList<Integer> 指定存放的元素类型为Integer
    ArrayList<Integer> list2=new ArrayList<>(10);
    list1.add(1);//第一次add时,底层数组size为10
    list1.add(2);
    list1.add(3);

    //ArrayList(Collection<? extends E> c)
    //参数c必须实现了Collection接口,是E的子类或E本身类型
    //list3的元素与list2相同
    ArrayList<Integer> list3=new ArrayList<>(list2);
}

        使用不带参数newArrayList对象时,默认size为0,当第一次add时,底层数组size为10,当数组需要扩容时,是以当前数组size的1.5倍进行扩容

        4.2 ArrayList的常用方法

        ArrayList提供方法比较多,但常用方法如下所示:

方法解释
boolean add(E e)尾插 e
void add(int index, E e)将 e 插入到 index位置
boolean addAll(Collection<? extends E> c)尾插 c 中的元素
E remove(int index)删除 index位置的元素
boolean remove(Object o)删除遇到的第一个 o
E get(int index)获取下标 index 位置的元素
E set(int index, E e)将下标 index位置元素设为 e
void clear()清空
boolean contains(Object o)判断 o是否在线性表中
int indexOf(Object o)返回第一个 o所在下标
int lastIndexOf(Object o)返回最后一个 o所在下标
List<E> subList(int fromIndex, int toIndex)截取部分list
public static void main(String[] args) {
    ArrayList<Integer> list1=new ArrayList<>(10);
    list1.add(1);
    list1.add(2);
    list1.add(3);
    list1.add(4);

    System.out.println(list1);// 1 2 3 4
    //获取list1中有效元素的个数并打印
    System.out.println(list1.size());//4

    System.out.println("====");
    //获取和设置index位置的元素
    System.out.println(list1.get(2));//3
    list1.set(2,99);
    System.out.println(list1.get(2));//99

    System.out.println("====");
    //在index位置插入value
    list1.add(2,88);
    System.out.println(list1);//1 2 88 99 4

    System.out.println("====");
    //删除指定元素
    list1.remove(new Integer(88));
    System.out.println(list1);//1 2 99 4
    //删除index位置的元素   index不能超过list1的有效元素个数
    list1.remove(2);
    System.out.println(list1);// 1 2 4

    System.out.println("====");
    //检查list1中是否包含value
    System.out.println(list1.contains(99));//false
    System.out.println(list1.contains(2));//true

    System.out.println("====");
    list1.add(2);
    list1.add(1);
    System.out.println(list1);//1 2 4 2 1
    //获取第一次出现value的下标
    System.out.println(list1.indexOf(1));//0
    //获取最后一次出现value的下标
    System.out.println(list1.lastIndexOf(1));//4

    System.out.println("====");
    //截取list1   List<E> subList(int fromIndex, int toIndex)
    List<Integer> list2=list1.subList(1,3);
    System.out.println(list2);//2 4

    //截取的list2并没有分配内存,只是list2这个引用指向下标为1~2的元素
    list2.set(0,10);
    System.out.println(list1);// 1 10 4 2 1
    System.out.println(list2);//10  4
}

        

        4.3 ArrayList的遍历

        ArrayList 可以使用三方方式遍历:for循环+下标、foreach、使用迭代器。

public static void main(String[] args) {
    ArrayList<Integer> list=new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    //for循环遍历
    for(int i=0;i<list.size();i++){
        System.out.print(list.get(i)+" ");
    }
    System.out.println();
    //foreach遍历
    for (Integer x:list){
        System.out.print(x+" ");
    }
    System.out.println();
    //迭代器遍历
    Iterator<Integer> it=list.iterator();
    while (it.hasNext()){
        System.out.print(it.next()+" ");
    }
}

        4.4 ArrayList的扩容机制

        ArrayList是一个动态类型的顺序表,即:在插入元素的过程中会自动扩容。以下是ArrayList源码中扩容方式:

        检测是否需要扩容,如果需要调用grow函数;估计容量大小,初步估计按1.5倍扩容,若用户所需超过估计的1.5倍大小,按用户所需大小扩容;扩容前进行检测是否能扩容;使用copyOf进行扩容。

五、ArrayList的具体使用

        5.1 简单洗牌算法

public class Card {
    //花色
    private String design_and_color;
    //数值
    private int value;

    public Card(String design_and_color, int value) {
        this.design_and_color = design_and_color;
        this.value = value;
    }

    @Override
    public String toString() {
        return "花色:"+design_and_color+" 数值:"+value;
    }

    public String getDesign_and_color() {
        return design_and_color;
    }

    public void setDesign_and_color(String design_and_color) {
        this.design_and_color = design_and_color;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}
public class CardText {
    //花色集合  红桃 ♥   黑桃  ♠   方块♦  梅花 ♣
    public static final String[] design_and_colors= {"♥", "♣", "♠", "♦"};
    //买一副牌
    public static List<Card> buyCard(){
        /*没有大小王,共52张牌,J Q K 分别用11 12 13代替*/
        List<Card> card=new ArrayList<>(52);
        for (int i = 0; i < 4; i++) {
            for(int j=1;j<=13;j++){
                Card card1=new Card(design_and_colors[i],j);
                card.add(card1);
            }
        }
        return card;
    }
    //洗牌
    public static  void brushCard(List<Card> cards){
        for (int i = 51; i >0 ; i--) {
            Random random=new Random(i);
            int j=random.nextInt(i);
            swap(cards,i,j);
        }
    }
    //交换两张牌
    public  static <j> void swap(List<Card> cards, int i,int j){
        Card tmp=cards.get(i);
        cards.set( i,cards.get(j));
        cards.set( j,tmp);

    }
    public static void main(String[] args) {
        //取一副牌
        List<Card> card=buyCard();
        System.out.println("拿到一副牌:");
        System.out.println(card);
        //洗牌
        brushCard(card);
        System.out.println("洗牌后:");
        System.out.println(card);
        //发牌 三人轮流拿牌,每人五张
        List<List<Card>> hands=new ArrayList<>();//hands代表三人各自取的牌
        hands.add(new ArrayList<>());//new ArrayList<>()代表每人手中的牌的集合
        hands.add(new ArrayList<>());
        hands.add(new ArrayList<>());
        for(int i=0;i<5;i++){
            for(int j=0;j<3;j++){
                hands.get(j).add(card.remove(0));
            }
        }
        System.out.println("第一个人手中的牌:");
        System.out.println(hands.get(0));

        System.out.println("第二个人手中的牌:");
        System.out.println(hands.get(1));

        System.out.println("第三个人手中的牌:");
        System.out.println(hands.get(2));
        System.out.println("剩余的牌:");
        System.out.println(card);
    }
}

        5.2 杨辉三角

               杨辉三角题目链接

public List<List<Integer>> generate(int numRows) {
    List<List<Integer>> list=new ArrayList<>();
    //设置第一行
    List<Integer> list2=new ArrayList<>();
    list2.add(1);
    list.add(list2);
    //设置剩余行
    for(int i=1;i<numRows;i++){
        //设置当前行
        List<Integer> tmp=new ArrayList<>();
        //设置当前行第一个数
        tmp.add(1);

        //获取前一行
        List<Integer> preRow=list.get(i-1);
        //设置当前行其他数
        for(int j=1;j<i;j++){
            int a=preRow.get(j-1)+preRow.get(j);
            tmp.add(a);
        }
        //设置当前行最后一个数
        tmp.add(1);

        list.add(tmp);
    }
    return list;
}

六、ArrayList的问题

        1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后移动,时间复杂度为O(N)。

        2. 增容需要申请新空间,拷贝数据,释放旧空间,有不小的消耗。

        3. 增容一般是呈1.5倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到150,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了45个数据空间。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1007950.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LVS负载均衡群集NAT模式

LVS负载均衡群集NAT模式 一、集群与分布式1.1、集群的含义1.2、lvs模型1.3、系统性能扩展方式1.4、群集的三种类型1.4.1、负载均衡群集1.4.2、高可用群集1.4.3、高性能运算群集 1.5、LVS的负载调度算法1.5.1、轮询1.5.2、加权轮询1.5.3、最少连接1.5.4、加权最少连接1.5.5、ip_…

【Spring源码解析】一文读懂Spring注入模型:开发者必备知识

文章目录 什么是注入模型注入模型的种类案例分析例子一创建Bean对象创建配置类重写后置处理器创建测试类执行测试方法分析 例子二改写站点类&#xff0c;去掉Autowired注解重写后置处理器执行测试方法分析思考 ✨这里是第七人格的博客✨小七&#xff0c;欢迎您的到来~✨ &#…

华为云云耀云服务器L实例评测|怎么搭建企业综合Web平台

前言 记得2019年&#xff0c;公司搞混合云的时候&#xff0c;测试过多家公有云&#xff0c;其中就有华为云。因公司也在深圳&#xff0c;项目也比较急&#xff0c;我司业务上云经验又不足&#xff0c;华为官方获悉情况后&#xff0c;第二天就派了4人小团队到我司来交流&#x…

金蝶云星空与金蝶云星空对接集成发货通知单查询打通发货通知单新增

金蝶云星空与金蝶云星空对接集成发货通知单查询打通发货通知单新增 数据源平台:金蝶云星空 金蝶K/3Cloud结合当今先进管理理论和数十万家国内客户最佳应用实践&#xff0c;面向事业部制、多地点、多工厂等运营协同与管控型企业及集团公司&#xff0c;提供一个通用的ERP服务平台…

加载动态库失败(loadLibrary返回为空 GetLastError126)解决办法 dll有依赖的dll缺失

问题&#xff1a;加载动态库失败&#xff08;loadLibrary返回为空&#xff09; 排除&#xff1a;64位也对。平台相同。 错误&#xff1a;至少找不到一个必需的隐式或转发依赖项。这个不影响。 SmartPay_PGL.dll下的四个dll&#xff0c;则是他所依赖的四个dll。因为我这里有缺失…

破天荒呀!小杜微信有名额了

写在前面 小杜粉&#xff0c;众所周知前面加小杜微信为好友的基本都是由名额限制的。一般都是付费进入社群且进行备注&#xff0c;小杜才会长期保留微信好友。主要由于&#xff0c;添加的人数太多了&#xff0c;微信账号人数名额有限。因此&#xff0c;小杜过一段时间&#xf…

在线会计软件推荐:高效实用的选择解析

如果您始终在密切关注Zoho&#xff0c;您一定知道&#xff0c;我们的软件在一个接一个的增加&#xff0c;为的是构建出一套可以全面在线协作、提升业务生产力的应用系统&#xff0c;我们始终致力于为各类企业构建完整的业务应用&#xff0c;以便他们在Zoho上运行整个业务系统。…

操作系统OS的发展历史和分类

1.手工操作阶段 使用纸带机&#xff0c;输入输出速度慢。但计算机速度快&#xff0c;导致计算机资源大部分时间处于闲置状态。主要缺点:用户独占全机、人机速度矛盾导致资源利用率极低。 2.批处理阶段 1.单道批处理系统 引入脱机输入/输出技术&#xff08;用外围机磁带完成…

Polygon ID:不仅仅是生物识别的人格证明

1. 引言 2023年7月V神在博客 What do I think about biometric proof of personhood? 中指出&#xff1a; 其中的risks包括&#xff1a;不可避免的隐私泄露、人们匿名浏览互联网的能力进一步削弱、威权政府的胁迫&#xff0c;以及在去中心化的同时可能不安全。 Polygon ID致…

【vue】vue 中插槽的三种类型:

文章目录 一、匿名插槽&#xff1a;二、具名插槽&#xff1a;三、作用域插槽 一、匿名插槽&#xff1a;<slot></slot> 1.没有为插槽指定名称 2.通过slot标签可以添加匿名插槽 3.在使用组件的时候&#xff0c;组件中的内容会填充到所有匿名插槽的位置&#xff0c;所…

知识库网站如何搭建?需要注意这五个要点!

正因为知识库提供结构化知识库来记载信息和知识&#xff0c;便于团队沉淀经验、共享资源&#xff0c;形成完整的知识体系并持续进化​&#xff0c;使得它成为当前企业发展新宠。 构建自己/团队的知识库是一个良好的习惯&#xff0c;可以提高工作和学习效率&#xff0c;以下是一…

SpringMVC之JSON数据返回与异常处理机制

目录 一.SpringMVC的JSON数据返回 1.导入Maven依赖 2.配置spring-mvc.xml 3.ResponseBody注解的使用 3.1案例演示 1.List集合转JSON 2.Map集合转JSON 3.返回指定格式String 4. ResponseBody用法 5.Jackson 5.1介绍 5.2常用注解 二.异常处理机制 1.为什么要全局异常处…

$ref赋值之后,子组件不渲染(刷新后,$ref父组件传值,子组件不更新数据问题)

在父组件中&#xff0c;点击搜索&#xff0c; 通过this.$refs传值给子组件 this.$refs.GoodsClassNav.paramsAll.keyword key; 子组件结果中不显示&#xff0c; 但是打印this.$refs.GoodsClassNav.paramsAll.keyword&#xff0c;可以打印到最新的值&#xff0c;点击子组件中…

SpringCloud在idea中一键启动项目

1、如下图文件中加上&#xff1a; <component name"RunDashboard"><option name"configurationTypes"><set><option value"SpringBootApplicationConfigurationType" /></set></option></component>…

CS5817规格书|CS5817芯片参数|多功能便携式显示器方案芯片规格

CS5817支持最高4K 60Hz是集睿致远&#xff08;ASL&#xff09; 新推出的多功能显示控制器芯片&#xff0c;CS5817产品可应用于便携显示器、电竞显示器、桌面显示器、一体式台式机和嵌入式显示系统。 Type-C/DP/HDMI2.0输入转LVDS/eDP/VBO 芯片, 高度集成了多种输入输出接口, 并…

QtCharts详细介绍及其使用

QtCharts模块 QtCharts是Qt框架中的一个模块&#xff0c;用于创建各种图表和数据可视化。它提供了一组功能强大且易于使用的类&#xff0c;使开发人员能够轻松地在应用程序中添加各种交互式图表。 QtCharts模块支持多种常见类型的图表&#xff0c;包括折线图、柱状图、饼图、…

浅谈C++|STL之set篇

一.set 1.1set基本概念 特点&#xff1a; 所有元素在插入时&#xff0c;会自动排序&#xff0c;并且不能插入重复元素。 本质&#xff1a; set/multiset属于关联式容器&#xff0c;底层是红黑树。 set/multiset区别 1.set不允许容器中有重复的元素 2.multiset允许容器中有重复…

FFmpeg入门及编译

文章目录 前言一、FFmpeg 简介二、基本组成1、封装模块 - AVFormat2、编解码模块 - AVCodec3、滤镜模块 - AVFilter4、视频图像转换计算模块 - swscale5、音频转换计算模块 - swresample6、AVUtil - 核心工具库7、AVDevice - 硬件采集&#xff0c;加速&#xff0c;显示 三、命令…

教学必备工具

大家好&#xff0c;今天要给大家介绍一个超级方便的工具——易查分&#xff01;利用易查分&#xff0c;我们可以轻松制作一个便捷高效的作业查询系统&#xff0c;让作业查询变得简单又高效。下面就让我来为大家详细介绍一下易查分的使用教程吧&#xff01; 是不是想有个自己的分…

【Java】-【使用jxl操作excel】

文章目录 下载jxl包并引用基本使用多sheet页使用并与MySQL/Oracle数据库连接 报错excel文件读写报错&#xff1a;jxl.read.biff.BiffException: Unable to recognize OLE stream原因&#xff1a;文件版本不兼容&#xff0c;jxl只支持excecl03版解决办法 下载jxl包并引用 jxl.j…