Java学习苦旅(十六)——List

news/2024/10/21 19:39:58/

本篇博客将详细讲解Java中的List。

文章目录

  • 预备知识——初识泛型
    • 泛型的引入
    • 泛型小结
  • 预备知识——包装类
    • 基本数据类型和包装类直接对应关系
    • 装包与拆包
  • ArrayList
    • 简介
    • ArrayList使用
      • ArrayList的构造
      • ArrayList常见操作
      • ArrayList遍历
  • 结尾

预备知识——初识泛型

泛型的引入

我们之前实现过的顺序表,只能保存int类型的元素,如果现在需要保存指向String类型对象的引用的顺序表,请问应该如何解决?

这个时候就需要引入泛型这个概念了。

泛型的意义:

  • 自动对类型进行检查
  • 自动对类型进行强制类型的转换

示例代码:

class MyArrayList<E> {private E[] elem;private int usedSize;public MyArrayList() {this.elem = (E[]) new Object[10];}public void add(E val) {this.elem[usedSize] = val;usedSize++;}public E get(int pos) {return this.elem[pos];}
}public class TestDemo {public static void main(String[] args) {MyArrayList<String> myArrayList = new MyArrayList<>();myArrayList.add("ABC");myArrayList.add("DEF");System.out.println(myArrayList.get(1));}
}

执行结果为:

image-20220228143543228

泛型小结

  1. 泛型是为了解决某些容器、算法等代码的通用性而引入,并且能在编译期间做类型检查。

  2. 泛型利用的是 Object 是所有类的祖先类,并且父类的引用可以指向子类对象的特定而工作。

  3. 泛型是一种编译期间的机制,即 MyArrayList<Integer> 和MyArrayList<String> 在运行期间是一个类型。

  4. 泛型是 java 中的一种合法语法,标志就是尖括号<>。

预备知识——包装类

基本数据类型和包装类直接对应关系

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

装包与拆包

示例代码

Integer a = 123;//隐式的装包
int b = a;//隐式的拆包Integer a2 = Integer.valueOf(123);//显式的装包
Integer a3 = new Integer(123);//显式的装包int b2 = a2.intValue();//显式的拆包

ArrayList

简介

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

说明

  1. ArrayList实现了RandomAccess接口,表明ArrayList支持随机访问。

  2. ArrayList实现了Cloneable接口,表明ArrayList是可以clone的。

  3. ArrayList实现了Serializable接口,表明ArrayList是支持序列化的。

  4. 和Vector不同,ArrayList不是线程安全的,在单线程下可以使用,在多线程中可以选择Vector或者CopyOnWriteArrayList。

  5. ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表。

ArrayList使用

ArrayList的构造

方法解释
ArrayList()无参构造
ArrayList(Collection<? extends E> c)利用其他Collection构建ArrayList
ArrayList(int initialCapacity)指定顺序表初始容量

示例代码

public static void main(String[] args) {List<Integer> list1 = new ArrayList<>();//构造一个空的列表List<Integer> list2 = new ArrayList<>(10);//构造一个具有10个容量的列表list2.add(1);list2.add(2);list2.add(3);ArrayList<Integer> list3 = new ArrayList<>(list2);//list3构造好之后,与list2中的元素一致
}

结论:

如果ArrayList调用,不带参数的构造方法,那么顺序表的大小是0。当第一次add的时候,整个顺序表才变为了10,当这10个放满了,开始扩容,以1.5倍的方式进行扩容。

如果调用的是给定容量的构造方法,那么顺序表的大小是所给的容量,放满之后还是以1.5倍进行扩容。

ArrayList常见操作

方法解释
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

示例代码

List<String> list = new ArrayList<>();
list.add("abc");
list.add("def");
list.add("ABC");
list.add("EFG");
System.out.println(list);
System.out.println(list.size());//获取list中有效元素个数
System.out.println("=========更改指定元素==========");
System.out.println(list.get(1));
list.set(1,"xyz");
System.out.println(list.get(1));
System.out.println("=========插入指定元素==========");
list.add(1,"LMN");//在list的index位置插入指定元素,index及后续的元素统一往后移动一个位置
System.out.println(list);
System.out.println("=========删除指定元素==========");
list.remove("ABC");//删除指定元素,找到了就删除,该元素之后的元素统一往前移动一个位置
System.out.println(list);
if(list.contains("OPQ")) {list.add("OPQ");
}
System.out.println("===查找指定元素第一次出现的位置===");
System.out.println(list.indexOf("EFG"));//indexOf从前往后找
System.out.println(list.lastIndexOf("EFG"));//lastIndexOf从后往前找
System.out.println("============================");
List<String> ret = list.subList(1,3);
System.out.println(ret);list.clear();
System.out.println(list.size());

执行结果为:

image-20220228191007198

ArrayList遍历

示例代码

List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
//直接打印
System.out.println(list);
//使用for循环
for (int i = 0; i < list.size(); i++) {System.out.print(list.get(i) + " ");
}
System.out.println();
//使用for-each
for (Integer s : list) {System.out.print(s + " ");
}
System.out.println();
//迭代器打印——Iterator
Iterator<Integer> it = list.iterator();
while(it.hasNext()) {System.out.print(it.next() + " ");
}
System.out.println();
//迭代器打印——ListIterator
ListIterator<Integer> it1 = list.listIterator();
while(it1.hasNext()) {System.out.print(it1.next() + " ");
}
System.out.println();

执行结果为:

image-20220228193049060

结尾

本篇博客到此结束。
上一篇博客:Java学习苦旅(十五)——异常
下一篇博客:Java学习苦旅(十七)——栈和队列


http://www.ppmy.cn/news/1295673.html

相关文章

本机javaweb项目在其他设备上展示

两台电脑在统一网络情况下&#xff1a; 本机winr打开黑窗口输入ipconfig&#xff0c;回车查看自己本机的IPv4地址 如果没有ping成功&#xff0c;把发布web项目的电脑防火墙全关了&#xff0c;重试。ping成功了往下看 前端的后端接口配置把localhost换成本机的IPV4地址192.168…

【量化金融】《证券投资学》吴晓求(第四版)(更新中)

正儿八经学学证券投资学 第一篇 基本知识第1章 证券投资工具名词解释简答题 第2章 证券市场名词解释简答题 第3章 资产定价理论及其发展名词解释 第二篇 基本分析第4章 证券投资的宏观经济分析名词解释 第三篇 技术分析第四篇 组合管理第五篇 量化分析与交易策略 第一篇 基本知…

深入了解Spring框架

一、前言 Spring框架是一个广泛应用于企业级Java应用程序开发的轻量级、开源的框架。它提供了全面的基础设施支持&#xff0c;使开发者能够专注于业务逻辑的实现而不必过多关注底层的技术细节。本文将深入探讨Spring框架的实际应用和一些最佳实践&#xff0c;帮助开发者更好地利…

三、C#面向对象编程(接口与实现)

在C#中&#xff0c;接口是一种定义方法但不包含实现的方式&#xff0c;可以被多个类实现以支持不同的行为。通过接口&#xff0c;我们可以定义一组标准的成员&#xff0c;让类遵循特定的契约。 下面是一个关于接口和实现的简单示例&#xff1a; // 定义一个接口 public inter…

使用Docker-Compose部署MySQL一主二从同步高可用MHA集群

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容准备mysql一主二从同步集群一主二从同步集群规划需要安装docker和docker-compose命令形式安装安装docker安装docker-compose 宝塔面板形式安装 部署Master节点的docker-compose.yaml文件部署MySQL从节点1的docker-compose.…

HPM6750开发笔记《DMA接收和发送数据UART例程深度解析》

目录 概述&#xff1a; 端口设置&#xff1a; 代码分析&#xff1a; 运行现象&#xff1a; 概述&#xff1a; DMA&#xff08;Direct Memory Access&#xff09;是一种计算机系统中的数据传输技术&#xff0c;它允许数据在不经过中央处理器&#xff08;CPU&#xff09;的直…

MYSQL双主节点–更换ip

MYSQL双主节点–更换ip 一、更换双主节点ip 1.停止mysql服务 #安装了supervisor supervisorctl stop mysql #未安装 systemctl stop mysqld2.修改网卡配置信息 注&#xff1a;ens33是网卡名称&#xff0c;可能网卡不叫ens33 vi /etc/sysconfig/network-scripts/ifcfg-ens333…

JVM工作原理与实战(九):类加载器-启动类加载器

专栏导航 JVM工作原理与实战 RabbitMQ入门指南 从零开始了解大数据 目录 专栏导航 前言 一、启动类加载器 二、通过启动类加载器去加载用户jar包 1.放入jre/lib目录进行扩展 2.使用参数进行扩展 总结 前言 JVM作为Java程序的运行环境&#xff0c;其负责解释和执行字节码…