Day9.集合,List接口

Java高级特性

第一章集合框架和泛型

技能目标:

​ 会使用List接口及实现类

​ 会使用Map接口及实现类

​ 掌握Iterator接口的使用

​ 了解泛型类、泛型接口使用

1.1认识集合

在开发应用程序时,如果想存储多个同类型的数据,可以使用数组来实现,但是使用数组存在以下一些明显的缺陷:

​ 1.数组的长度固定不变,不能很好的适应元素数量动态变化的情况

​ 2.可通过数组名.length获取数组的长度,却无法直接获取数组中的实际存储的元素个数

​ 3.数组采用在内存中分配连续空间的存储方式存储,根据元素信息查找时效率比较低,需要多次比较

​ 从以上分析可以看出数组在处理一些问题时存在明显的缺陷,针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用于不同应用场合。

​ 从以上分析可以看出数组在处理一些问题时存在明显的缺陷,针对数组的缺陷,Java提供了比数组更灵活、更实用的集合框架,可大大提高软件的开发效率,并且不同的集合可适用不同应用场合。

​ Java集合框架提供了一套性能优良、适用方便的接口和类,他们都位于java.util包中,其中主要内容及彼此之间的关系如下:(画图)
在这里插入图片描述

​ 从上图可以看出,Java集合类主要由Map接口和Collection接口派生而来的,其中Collection接口有两个常用接口,即List接口和Set接口,所以通常说Java集合框架由3大类接口构成(Map接口、List接口和Set接口)。本章内容就是围绕这个3大类接口进行的。

注意
虚线框表示接口或抽象类,实现框表示开发中常用的实现类。

1.2List接口

Collection接口是最基本的集合接口,可以存储一组不唯一、无序的对象。List接口继承自Collection接口,是有序集合。用户可使用索引访问List接口中的元素,类似于数组。List接口允许存放重复元素,也就是List可以存储一组不唯一、有序的对象。

List接口常用的实现类有ArrayList和LinkedList。

1.使用ArrayList类动态存储数据

针对数组的一些缺陷,Java集合框架提供了ArrayList集合类,对数组进行了封装,实现了长度可变的数组,而且和数组采用相同的存储方式,在内存中分配了连续的空间,如下图(画图),所以,经常称ArrayList为动态数组。但是它不等同于数组,ArrayList集合中可以添加任何类型的数据,并且添加的数据都将转换成Object类型,而在数组中只能添加同一个数据类型的数据。
在这里插入图片描述

ArrayList类提供了很用于操作数据,如表1-1中列出的是ArrayList类的常用方法

​ 表1-1 ArrayList类的常用方法

方法说明
boolean add(Object o)在列表的末尾添加元素o,起始索引位置从0开始
void add(int index,Object o)在指定的索引位置添加元素o,在索引位置必须介于0和列表中元素个数之间
int size()返回列表中的元素个数
Object get(int index)返回指定索引位置处的元素,取出的元素是Object类型,使用前需要进行强制类型转换
void set(int index,Object obj)将index索引位置的元素替换为obj元素
boolean contains(Object o)判断列表中是否存在指定元素o
int indexOf(Object obj)返回元素在集合出现的索引位置
boolean remove(Object o)从列表中删除元素o
Object remove(int index)从列表中删除指定位置的元素,起始索引位置从0开始

例1
使用ArrayList常用方法动态操作数据

​ 实现步骤如下:

​ 1).导入ArrayList对象,并添加数据

​ 2)创建ArrayList对象,并添加数据

​ 3)判断集合中是否包含某个元素

​ 4)移除索引为0的元素

​ 5)把索引为1的元素替换为其他元素

​ 6)输出某个元素所在的索引位置

​ 7)清空ArrayList集合中的数据

​ 8)判断ArrayList集合中是否包含数据

package Test1;

import java.util.ArrayList;

/**
 * @作者:Xem626
 * @date: 2022/7/12 19:30
 * @TODO
 */
public class Test1 {
    public static void main(String[] args) {


        /*
         调用了ArrayList无参的构造方法,创建了集合对象,常用的ArrayList类的构造方法
         还有一个带参数的重载版本,即ArrayList(int initialCapacity),
         他构造一个具有指定容量的空列表
         */
        ArrayList list=new ArrayList<>();
        list.add("艾琳");
        list.add("后羿");
        list.add("守约");
        //判断集合是否含有江南
        boolean a=list.contains("江南");
        System.out.println(a);
        //把索引为0的元素移除
        Object remove=list.remove("艾琳");
        System.out.println("-----------------------");
        //替换元素
        list.set(0,"路明非");

        for(int i=0;i<list.size();i++){
            //取出来的数据是object类型,如需要使用,需要强制类型转换
            String string= (String) list.get(i);
            System.out.println(string);

        }
        System.out.println("------------------");
        System.out.println(list.indexOf("路明非"));


        //清空list元素
        list.clear();
        System.out.println("------------------");
        //使用增强for循环比普通循环更简单,不需要考虑下标越界
        for(Object object:list){
            String name= (String) object;
            System.out.println(name);
        }
    }
}

在这里插入图片描述
分析:

​ 在示例1中,1的代码调用ArrayList的无参构造方法,创建集合对象。常用的ArrayList类的构造方法还有一个带参数的重载版本,即ArrayList(int initialCapacity),它构造一个具有指定初始容量的空列表。

​ 在2的代码将list集合中索引为0的元素删除,list集合的下标是从0开始,也就是删除了"艾琳",集合中现有元素为"后羿"和“守约”。

​ 在3的代码将list集合中索引为0的元素替换为"路明非",即将"后羿"替换为"路明非",集合中现有元素为"路明非"和"守约"。

​ 在4的代码是使用for循环遍历集合,输出集合中所有的元素。list.get(i)取出集合中索引为i的元素,并强制转换为String类型。

在5的代码为输出元素"零"所在索引位置,因集合中没有该元素,所以输出结果为-1.


​ 在6的代码块是使用增强for循环遍历集合,输出集合中没有该元素。增强for循环的语法在Java基础课程中讲过,这里不再赘述。可以看出,遍历集合时使用增强for循环比普通for循环在写法上更加简单方便,而且不用考虑下标越界的问题。

​ 在7的代码来判断list集合是否空,因为前面执行了list.clear()操作,所以集合已经为空,输出啥也没有。

注意:

​ 1.调用ArrayList类的add(Object obj)方法,添加到集合当中的数据将被转换为Object类型

​ 2.使用ArrayList类之间,需要导入相应的接口和类,代码如下

​ import.java.util.ArrayList

例2
​ 需求:使用ArrayList集合存储新闻标题信息(包含ID、名称、创建者),输出新闻标题的总数量及每条新闻标题的名称

​ 实现步骤:

​ 1).创建ArrayList对象,并添加数据

​ 2).获取新闻标题的总数

​ 3)遍历集合对象,输出新闻标题名称

1.创建一个NewTitle类

package Test1;

/**
 * @作者:Xem626
 * @date: 2022/7/12 20:15
 * @TODO
 */
public class NewTitle {
        private int Id;
        private String name;
        private String create;

    public int getId() {
        return Id;
    }

    public void setId(int id) {
        Id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCreate() {
        return create;
    }

    public void setCreate(String create) {
        this.create = create;
    }

    public NewTitle() {
    }

    public NewTitle(int id, String name, String create) {
        this.Id = id;
        this.name = name;
        this.create = create;
    }

}


2.实现代码

package Test1;

import java.util.ArrayList;
import java.util.List;

/**
 * @作者:Xem626
 * @date: 2022/7/12 20:17
 * @TODO
 */
public class Test2 {
    public static <newTitle> void main(String[] args) {

        NewTitle newTitle = new NewTitle(1, "汽车", "管理员");
        NewTitle newTitle1 = new NewTitle(2, "高考", "管理员");
        //多态
       //List list=new ArrayList();
        ArrayList arrayList=new ArrayList();
        arrayList.add(newTitle);
        arrayList.add(newTitle1);

        //获取新闻的标题总数
        System.out.println("获取新闻标题总数:"+arrayList.size());

        System.out.println("新闻标题为:");

        for(Object object:arrayList){
            //取出来的东西是NewTitle的object类型
            NewTitle newTitle2=(NewTitle) object;
            System.out.println(newTitle2.getName());

        }





    }
}

在这里插入图片描述
分析:

​ 在示例2中,ArrayList集合中存储的是新闻标题对象。在ArrayList集合中可以存储任何类型的对象。其中代码 List list =new ArrayList();是将接口List的引用指向实现类ArrayList的对象。在编程中将接口的引用指向实现类的对象是Java实现多态的一种形式,也是软件开发中实现低耦合的方式以,这样的用法可以大大提高程序的灵活性。随着编程经验的积累,开发者对这个用法的理解会逐步加深。

ArrayList集合因为可以使用索引来直接获取元素,所以优点是遍历元素和随机访问元素的效率比较高。但是由于ArrayList集合采用了和数组相同的存储方式,在内存中分配连续的空间,因此在添加和删除非尾部元素时会导致所有元素的移动,这就造成在插入、删除等操作频繁的应用场景下使用ArrayList会导致性能低下。所以数据操作频繁,最好使用LinkedList存储数据

2.使用LinkedList类动态存储数据

LinkedList类是List接口的链接列表实现类。它支持实现所有List接口可选的列表的操作,并且允许元素值是任何数据,包括null。

​ LinkedList类采用链表存储方式存储数据,优点在于插入、删除元素时效率比较高,但是LinkedList类的查找效率很低

​ 它除了包含ArrayList类所包含的方法外,还提供了如下表的一些方法,可以在LinkedList类的首部或尾部进行插入、删除操作。

表1.2

方法说明
void addFirst(Object obj)将指定元素插入到当前集合的首部
void addLast(Object obj)将指定元素插入到当前集合的尾部
Object getFirst()获得当前集合的第一个元素
Object getLast()获得当前集合的最后一个元素
Object removeFirst()移除并返回当前集合的第一个元素
Object removeLast()移除并返回当前集合的最后一个元素

例3:​
需求:

​ 使用LinkedList集合存储新闻标题(包含ID、名称、创建者),实现获取、添加及删除头条和末条新闻标题信息功能,并遍历集合
实现步骤如下:

​ 1.创建LinkedList对象,并添加数据

​ 2.添加头条和末条新闻标题

​ 3.获取头条和末条新闻标题信息

​ 4.删除头条和末条新闻标题

(1)借用上面案例的NewTiltle的业务模型

​ (2)实现需求

package Test1;

import java.util.LinkedList;

/**
 * @作者:Xem626
 * @date: 2022/7/12 20:51
 * @TODO
 */
public class Test3 {
    public static void main(String[] args) {
        LinkedList list =new LinkedList();

        NewTitle newTitle = new NewTitle(1, "汽车", "管理员");
        NewTitle newTitle1 = new NewTitle(2, "高考", "管理员");

        list.add(newTitle);
        list.add(newTitle1);
        NewTitle newTitle2=new NewTitle(3,"娱乐","管理员");

        list.addFirst(newTitle2);
        NewTitle newTitle3=new NewTitle(4,"体育","管理员");


        list.addLast(newTitle3);
        System.out.println("获取新闻标题总数:"+list.size());

        System.out.println("新闻标题为:");

        for(Object object:list){

            NewTitle title=(NewTitle) object;
            System.out.println(title.getName());


        }
        System.out.println("------------------");


        //获取当前集合的第一个元素
        Object first= list.getFirst();
        NewTitle first1=(NewTitle) first;
        System.out.println(first1.getName());

        //获取尾部元素
        Object last=list.getLast();
        NewTitle last1=(NewTitle) last;
        System.out.println(last1.getName());

        System.out.println("------------------------");

        //移除并返回第一个元素
        Object o=list.removeFirst();
        NewTitle o1=(NewTitle) o;
        System.out.println(o1.getName());
        System.out.println("------------------");
        for(Object o2:list){

            NewTitle title=(NewTitle) o2;
            System.out.println(title.getName());


        }
        System.out.println("--------------------");
        //移除并返回最后一个元素
        Object o3=list.removeFirst();
        NewTitle o4=(NewTitle) o3;
        System.out.println(o4.getName());
        System.out.println("------------------");
        for(Object o5:list){

            NewTitle title=(NewTitle) o5;
            System.out.println(title.getName());


        }

    }
}

在这里插入图片描述

除了表1-2中列出的LinkedList类提供的方法外,LinkedList类和ArrayList类所包含的大部分方法都是一样的,主要的原因是因为他们都是List接口的实现类。由于ArrayList采用和数组一样的连续的顺序存储方法,当对数据频繁检索时效率较高,而LinkedList类采用链表存储方式,当数据添加,删除或修改比较多时,建议选择LinkedList类存储数据

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xem626

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值