【Java 集合框架】List、ArrayList 和 LinkedList 的使用

示例八: 将下标 index 位置元素设置为 element

System.out.println(list.set(2,3));

System.out.println(list);

// 结果为:99 和 [1, 2, 3]

示例九: 判断 o 是否在线性表中

System.out.println(list.contains(1));

// 结果为:true

示例十: 返回第一个 o 所在下标

System.out.println(list.indexOf(1));

// 结果为:0

示例十一: 返回最后一个 o 的下标

list.add(1);

System.out.println(list.lastIndexOf(1));

// 结果为:3

示例十二: 截取部分 list

List list2=list.subList(1,3);

System.out.println(list2);

// 结果为:[2, 3]

注意,当我们将 list2 通过 set 更改元素,其实对 list 也会有影响

list2.set(0,5);

System.out.println(list2);

System.out.println(list);

// 结果为:[5, 3] 和 [1, 5, 3, 1]

通过 subList 方法进行的截取,得到的集合的数值指向的地址和原集合中数值的地址是一样的

2. ArrayList

================================================================================

2.1 介绍


ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。其继承了 AbstractList,并实现了 List 接口。LinkedList 不仅实现了 List 接口,还实现了 Queue 和 Deque 接口,可以作为队列去使用。

ArrayList 类位于 java.util 包中,使用前需要引入它。

2.2 ArrayList 的构造方法


| 方法 | 描述 |

| — | — |

| ArrayList() | 无参构造 |

| ArrayList(Collection<? extends E> c) | 利用其他 Collection 构建 ArrayList |

| ArrayList(int initialCapacity) | 指定顺序表初始容量 |

示例一:

ArrayList list1 = new ArrayList<>();

示例二:

ArrayList list2 = new ArrayList<>(10);

// 该构造方法就是在构建时就将底层数组大小设置为了10

示例三:

List list = new ArrayList<>();

list.add(1);

list.add(2);

ArrayList list3 = new ArrayList<>(list);

Collection<? extends E> c 只要是具体类型都和 list3 是一样的集合都可以放入转化成 ArrayList

2.3 ArrayList 底层数组的大小


当我们使用 add 方法给 ArrayList 的对象进行尾插时,突然想到了一个问题:既然 ArrayList 的底层是一个数组,那么这个数组有多大呢?

为了解决这个问题,我进行了如下探索

  1. 跳转到 ArrayList 的定义,我们看到了 elementDataDEFAULTCAPACITY_EMPTY_ELEMENTDATA在这里插入图片描述
  1. 跳转到 elementData 的定义,我们可以了解 ArrayList 底层是数组的原因在这里插入图片描述
  1. 跳转到 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 的定义,初步分析得到这个数组其实是空的在这里插入图片描述

为什么这个数组是空的但存储元素的时候没有报异常呢?我们再去了解下 add 是怎样存储的

  1. 通过转到 ArrayList 的 add 方法的定义在这里插入图片描述
  1. 通过定义,不难发现,数组容量和 ensureCapacityInternal 这个东西有关,那我们就看看它的定义在这里插入图片描述
  1. 我们看里面的 calculateCapacity ,他有两个参数,此时数组为空,那么 minCapacity 就为 1。我们再转到 calculateCapacity 看看它的定义在这里插入图片描述
  1. 此时我们就好像可以与之前串起来了,当数组为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,就返回 DeFauLt_CAPACITYminCapacity(此时为1) 的最大值。DeFauLt_CAPACITY 其实是默认容量的意思,我们可以转到它的定义看看有多大在这里插入图片描述
  1. DeFauLt_CAPACITY 的值是10,故 calculateCapacity 函数此时的返回值为10,最后我们再确定一下 ensureExplicitCapacity 是干啥的在这里插入图片描述
  1. 此时 minCapacity 的值是10,而数组为空时数组长度为0,所以进入 if 语句,执行 grow 方法,我们继续转到 grow 的定义在这里插入图片描述

此时我们就可以了解,当我们创建一个 ArrayList 时,其底层数组大小其实是0。当我们第一次 add 的时候,经过 grow ,数组的大小就被扩容为了10。并且这大小为10的容量放满以后,就会按1.5倍的大小继续扩容。至于这个数组最大能存放多少,大家可以再转到 MAX_ARRAY_SIZE 的定义去查看。

3. LinkedList

=================================================================================

3.1 介绍


LinkedList 类是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

Java 的 LinkedList 底层是一个双向链表,位于 java.util 包中,使用前需要引入它

3.2 LinkedList 的构造方法


| 方法 | 描述 |

| — | — |

| LinkedList() | 无参构造 |

| LinkedList(Collection<? extends E> c) | 利用其他 Collection 构建 LinkedList |

示例一:

LinkedList list1 = new LinkedList<>();

示例二:

List list = new LinkedList<>();

list.add(1);

list.add(2);

LinkedList list2 = new LinkedList<>(list);

Collection<? extends E> c 只要是具体类型都和 list2 是一样的集合都可以放入转化成 LinkedList

4. 练习题

==========================================================================

  • 习题一

题目描述:

霍格沃茨学院有若干学生(学生对象放在一个 List 中),每个学生有一个姓名(String)、班级(String)和考试成绩(double)。某次考试结束后,每个学生都获得了一个考试成绩。遍历 list 集合,并把每个学生对象的属性都打印出来

本题代码:

class Student{

private String name;

private String classes;

private double score;

// 重写构造方法

public Student(String name, String classes, double score) {

this.name = name;

this.classes = classes;

this.score = score;

}

// 构造 get 和 set 方法

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getClasses() {

return classes;

}

public void setClasses(String classes) {

this.classes = classes;

}

public double getScore() {

return score;

}

public void setScore(double score) {

this.score = score;

}

// 重写 toString 方法

@Override

public String toString() {

return “Student{” +

“name='” + name + ‘’’ +

“, classes='” + classes + ‘’’ +

“, score=” + score +

‘}’;

}

}

public class TestDemo {

public static void main(String[] args) {

ArrayList students = new ArrayList<>();

students.add(new Student(“哈利波特”,“大二班”,95.5));

students.add(new Student(“赫敏格兰杰”,“小三班”,93));

students.add(new Student(“罗恩韦斯莱”,“小二班”,91));

for(Student s: students){

System.out.println(s);

}

}

}

// 结果为:

// Student{name=‘哈利波特’, classes=‘大二班’, score=95.5}

// Student{name=‘赫敏格兰杰’, classes=‘小三班’, score=93.0}

// Student{name=‘罗恩韦斯莱’, classes=‘小二班’, score=91.0}

  • 习题二

题目描述:

有一个 List 当中存放的是整形的数据,要求使用 Collections.sort 对 List 进行排序

该题代码:

public class TestDemo {

public static void main(String[] args) {

ArrayList list = new ArrayList<>();

list.add(3);

list.add(7);

list.add(1);

list.add(6);

list.add(2);

Collections.sort(list);

System.out.println(list);

}

}

// 结果为:[1, 2, 3, 6, 7]

补充:

Collections 是一个工具类,sort 是其中的静态方法,它是用来对 List 类型进行排序的

注意:

如果具体的类是类似于习题一那样的 Student 类,该类中含有多个属性,那就不能直接使用这个方法。要对 comparator 或者 comparable 接口进行重写,确定比较的是哪个属性才行

  • 习题三

题目描述:

输出删除了第一个字符串当中出现的第二个字符串中的字符的字符串,例如

String str1 = “welcome to harrypotter”;

String str2 = “come”;

// 结果为:wl t harrypttr

希望本题可以使用集合来解决

该题代码:

public static void removeS(String str1, String str2){

if(str1null || str2null){

return;

}

List list = new ArrayList<>();

int lenStr1=str1.length();

for(int i=0; i<lenStr1; i++){

char c = str1.charAt(i);

if(!str2.contains(c+“”)){

list.add©;

}

}

for(char ch: list){

System.out.print(ch);

}

}

5. 扑克牌小游戏

=============================================================================

我们可以通过上述所学,运用 List 的知识,去写一个关于扑克牌的逻辑代码(如:获取一副牌、洗牌、发牌等等)

class Card{

private String suit; // 花色

private int rank; // 牌面值

public Card(String suit, int rank){

this.suit=suit;

this.rank=rank;

}

@Override

public String toString() {

return "[ “+suit+” “+rank+” ] ";

}

}

public class TestDemo {

public static String[] suits = {“♣”, “♦”, “♥”, “♠”};

// 获取一副牌

public static List getNewCards(){

// 存放 52 张牌

List card = new ArrayList<>();

for(int i=0; i<4; i++){

for(int j=1; j<=13; j++) {

card.add(new Card(suits[i], j));

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

image

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!**

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

写在最后

还有一份JAVA核心知识点整理(PDF):JVM,JAVA集合,JAVA多线程并发,JAVA基础,Spring原理,微服务,Netty与RPC,网络,日志,Zookeeper,Kafka,RabbitMQ,Hbase,MongoDB,Cassandra,设计模式,负载均衡,数据库,一致性哈希,JAVA算法,数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算…

[外链图片转存中…(img-ZkpLL7LV-1713524953157)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 29
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值