当前位置: 首页 > news >正文

ArrayList类 (顺序表)

目录

一. ArrayList 基本介绍

二. ArrayList 中的法及其应用

1. 添加元素

(1) add()

(2) addAll()

2. 删除元素

(1) remove()

(2) removeAll()

3. 遍历元素

(1) for 循环遍历

(2) for - each 遍历

(3) 迭代器遍历

(4) 列表迭代器遍历

4. 判断

(1) cotains()

(2) containsAll()

(3) isEmpty()

5. 获取子列表

三. 模拟实现 ArrayList

1. 模拟实现添加元素

2. 模拟实现删除元素

3. 模拟实现判断

4. 验证是否正确


一. ArrayList 基本介绍

(1) ArrayList (顺序表) 继承于 List接口, 是Java集合框架的一部分.

(2) ArrayList 用于存放可重复, 有序的元素.

(3) ArrayList 底层使用数组来实现.

(4) ArrayList 的特点是 查找 的速度快 (因为可以直接通过下标查找), 添加/删除 元素的速度慢 (因为添加或删除之后还需要移动元素).

二. ArrayList 中的法及其应用

通过查看文档我们可以看到, ArrayList 类主要有以上几种方法. 我把其中比较重要的几个方法勾选了出来, 这些我们要重点熟悉掌握. 大家也可以自行翻阅文档进行学习. 

首先我们要在list里存放对象. 假设我们要存放Student类型的对象.

首先定义学生类:

public class Student {private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}public void setName(String name) {this.name = name;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object obj) {if (this == obj) {  //1. 如果this和obj指向同一个对象, 则返回true;return true;}if (obj instanceof Student) {  //2. 如果this和obj指向不同对象, 而且obj是Student类型的if (this.age == ((Student) obj).getAge() && this.name == ((Student) obj).getName()) {return true;}return false;}return false;}
}

1. 添加元素

(1) add()

add() 方法, 有两个版本: 版本一有一个参数, 版本二有两个参数. 

[1] add(E e)  将指定元素添加到末尾

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList);}
}

 

[2] add(int index, E element)  将指定元素插入指定位置.

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList);Student s4 = new Student("Jack",45);arrayList.add(1,s4);System.out.println(arrayList);}
}

(2) addAll()

addAll() 方法的基本作用是将一个列表添加到另一个列表中去. 与add() 类似, addAll() 方法也有两个版本:

[1] addAll(Collection e) 表示将另一列表添加到当前列表之后.

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList); // 打印arrayListStudent s4 = new Student("Jack",45);Student s5 = new Student("Bob", 55);Student s6 = new Student("Molly",31);ArrayList<Student> arrayList1 = new ArrayList<>();arrayList1.add(s4);arrayList1.add(s5);arrayList1.add(s6);System.out.println(arrayList1); // 打印arrayList1arrayList.addAll(arrayList1);System.out.println(arrayList); // 打印合并之后的arrayList}
}

 [2] addAll(intindex, Collection e) 表示在指定位置插入另一列表.

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList);Student s4 = new Student("Jack",45);Student s5 = new Student("Bob", 55);Student s6 = new Student("Molly",31);ArrayList<Student> arrayList1 = new ArrayList<>();arrayList1.add(s4);arrayList1.add(s5);arrayList1.add(s6);System.out.println(arrayList1);arrayList.addAll(1,arrayList1);System.out.println(arrayList);}
}

2. 删除元素

(1) remove()

remove() 方法, 参数可以传递下标, 也可以传递对象的引用. 作用都是把指定节点删除掉. 代码演示如下:

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList);arrayList.remove(0); // 传递下标删除元素System.out.println(arrayList);arrayList.remove(s2); // 传递对象删除元素System.out.println(arrayList);}
}

(2) removeAll()

与add()和addAll()的关系类似, remove()方法是删除单个元素, removeAll()方法是从一个列表里删除另一个列表中的所有元素.

因为我们在Student里重写了equals()方法, 所以只要两个对象的name和age属性一样, 那么就认为这两个对象是相同的.

import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList);ArrayList<Student> arrayList1 = new ArrayList<>();arrayList1.add(s1);arrayList1.add(s2);System.out.println(arrayList1);arrayList.removeAll(arrayList1);System.out.println(arrayList);}
}

3. 遍历元素

(1) for 循环遍历
import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);for (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));}}
}

(2) for - each 遍历
import java.util.ArrayList;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);for (Student stu: arrayList) {System.out.println(stu);}}
}

(3) 迭代器遍历
import java.util.ArrayList;
import java.util.Iterator;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);Iterator<Student> iterator = arrayList.iterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

(4) 列表迭代器遍历
  • 正序遍历:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);ListIterator<Student> iterator = arrayList.listIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}

  • 逆序遍历: 
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;public class demo {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);ListIterator<Student> iterator = arrayList.listIterator(arrayList.size()); // 相当于把迭代器插入到 size() 位置的前面. 从这里开始遍历while (iterator.hasPrevious()) {System.out.println(iterator.previous());}}
}

[注]: 这里我们需要注意一点:  给 listIterator() 传参数 就表示将迭代器插入到index位置的前面

 所以这里给listIterator() 传了一个arrayList.size(), 就相当于把迭代器插入到了 size() 位置的前面

4. 判断

(1) cotains()
public class demo1 {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList.contains(new Student("吴彦祖", 26)));System.out.println(arrayList.contains(new Student("周润发", 50)));}
}

(2) containsAll()
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;public class demo1 {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);ArrayList<Student> arrayList1= new ArrayList<>();arrayList1.add(s1);arrayList1.add(s2);System.out.println(arrayList.containsAll(arrayList1));}
}

(3) isEmpty()

判断当前顺序列表是否为空.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;public class demo1 {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);System.out.println(arrayList.isEmpty());arrayList.clear();System.out.println(arrayList.isEmpty());}
}

5. 获取子列表

ArrayList中, 获取一个顺序列表的子列表, 需要使用 subList() 方法

subList() 方法, 参数传一个区间(左闭右开), 表示要获取的子列表的区间.

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;public class demo1 {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);Student s4 = new Student("大师",99);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);arrayList.add(s4);System.out.println(arrayList);List<Student> sl = arrayList.subList(1,3); //获取区间[1,3) 左闭右开.System.out.println(sl);}
}

6. 获取下标

ArrayList中, 获取下标使用 indexOf() 方法:

public class demo2 {public static void main(String[] args) {Student s1 = new Student("刘德华",22);Student s2 = new Student("梁朝伟",24);Student s3 = new Student("吴彦祖",26);Student s4 = new Student("大师",99);ArrayList<Student> arrayList = new ArrayList<>();arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);arrayList.add(s4);System.out.println(arrayList.indexOf(s2));System.out.println(arrayList.indexOf(s3));}
}

三. 模拟实现 ArrayList

我们知道, Arraylist底层是基于数组实现的. 所以, 我们在模拟实现Arraylist的时候,, 就需要先创建于一个数组, 然后基于数组实现我们自己的Arraylist.

为了实现起来简单, 我们自己实现ArrayList只能存放 int 类型的元素.

public class MyArrayList {public int[] elem; //定义一个操作数组public int usedSize; //定义一个 "已使用空间"public MyArrayList() {this.elem = new int[10];}
}

如上图, 这是就是模拟顺序列表中的属性, 一个是数组elem(在创建对象时 被初始化为10) , 另一个是usedSize, 表示已使用空间 (也就是数组中的元素个数 / 数组的长度).

还有一个问题, 因为我们验证我们写的方法是否正确时 要打印数组, 所以我们还需要重写一下 toString 方法, 否则打印出来的一堆哈希码, 没有可读性.

    @Overridepublic String toString() {String str = "";for (int i = 0; i < size(); i++) {if (i == 0){str += "[";str += elem[i];str += ",";continue;}if (i == size()-1) {str += elem[i];str += "]";continue;}str += elem[i];str += ",";}return str;}

1. 模拟实现添加元素

判满方法:

    private boolean isFull () {if (usedSize == elem.length) {return true;}else {return false;}}
(1) 添加元素到末尾 
public void add(int data) { //添加元素到末尾.if (this.isFull()) { //如果数组满了, 对数组进行扩容.elem = Arrays.copyOf(elem, 2*elem.length);}elem[usedSize] = data;usedSize ++;}

先判断数组是不是满了: 如果满了, 就扩容; 如果没满, 就进行添加元素操作.

(2) 添加元素到指定位置
public void add(int index, int data) { // 添加元素到指定位置.if (this.isFull()) {elem = Arrays.copyOf(elem, 2*elem.length);}for (int i = size()-1; i >= index; i--) {elem[i+1] = elem[i]; // 把元素向后移一位.(把i位置的元素赋到它后面的位置)}elem[index] = data;usedSize++;}

 相同地, 我们还是先判断是不是数组满的: 如果满了, 就扩容; 如果没满, 就进行添加元素操作.

这里由于是添加到指定位置, 所以原先在指定位置的元素及其后面的所有元素就需要后移.

2. 模拟实现删除元素

获取列表长度方法:

  public int size() { // 求当前顺序表的长度.return this.usedSize;}
(1) 根据值删除元素
   public void remove (int data) {  //根据值删除元素for (int i = 0; i < size(); i++) { //先找到指定元素的下标if (elem[i] == data) {for (int j = i; j < size()-1; j++) {elem[j]= elem[j+1]; // 往前覆盖掉elem[i].}usedSize--;}}}

这里需要注意的点是: 删除元素 就是把指定元素的位置覆盖掉就可以了.

(2) 根据下标删除元素
    public void  removeIndex (int index) { // 根据下标删除元素for (int j = index; j < size()-1; j++) {elem[j] = elem[j+1];}usedSize--;}

3. 模拟实现判断

(1) contains
public boolean contains(int data) { // 判断是否包含指定元素datafor (int i = 0; i < size(); i++) {if (elem[i] == data) {return true;}}return false;}
(2) isEmpty()
public boolean isEmpty() {  //判断当前顺序列表是否为空if (this.usedSize == 0) {return true;}else {return false;}}
(3) clear()
public void clear() { // 清空当前顺序列表.this.usedSize = 0;}

4. 验证是否正确

public class Main {public static void main(String[] args) {MyArrayList myArrayList = new MyArrayList();//1. 验证add (添加到元素末尾)myArrayList.add(1);myArrayList.add(1);myArrayList.add(2);myArrayList.add(3);myArrayList.add(4);myArrayList.add(5);System.out.println(myArrayList);//2. 验证 add (添加到指定位置)myArrayList.add(2,99);System.out.println(myArrayList);//3. 验证 remove (根据值删除元素)myArrayList.remove(2);System.out.println(myArrayList);//4. 验证 remove (根据下标删除元素)myArrayList.removeIndex(1);System.out.println(myArrayList);//5. 验证 containsSystem.out.println(myArrayList.contains(99));//6. 验证 isEmpty() 和 clear()System.out.println(myArrayList.isEmpty());myArrayList.clear();System.out.println(myArrayList.isEmpty());}
}

通过打印结果我们发现, 我们模拟实现的 ArrayList 没有任何问题~~ 


http://www.mrgr.cn/news/81184.html

相关文章:

  • 开放词汇目标检测(Open-Vocabulary Object Detection, OVOD)综述
  • Mysql高级部分总结(二)
  • 软件测试丨性能测试工具-JMeter
  • 大恒相机开发(3)—大恒相机工业检测的实际案例
  • QEMU安装使用@FreeBSD
  • 股票行情分析api接口怎么用?
  • Linux的VIM基本操作
  • 两台主机传送数据: transfer files between servers使用rsync命令
  • Linux网络——UDP的运用
  • UE5 移植Editor或Developer模块到Runtime(以运行时弹窗为例)
  • Dapper
  • C++设计模式:组合模式(公司架构案例)
  • 【IC】TSMC先进工艺发展历程--从N5到A16,从A16到未来
  • 某尝准app请求体响应加密分析
  • 多行为级联24|多行为推荐的超图增强级联图卷积网络
  • HashMap源码深度解析
  • CentOS HTTPS自签证书访问失败问题的排查与解决全流程
  • SpringCloud 运用(2)—— 跨服务调度
  • 访谈积鼎科技总经理:国产CFD软件发展与未来趋势展望
  • GitCode 光引计划投稿|JavaVision:引领全能视觉智能识别新纪元
  • Centos7安装k8s集群
  • node.js的异步工作之---回调函数与回调地狱
  • Pandas系列|第三期:Pandas中访问数据
  • 2024年A股最新退市规则
  • linux上抓包RoCEv2
  • Day1 苍穹外卖前端 Vue基础、Vue基本使用方式、Vue-router、Vuex、TypeScript