实现List接口的ArrayList和LinkedList

package study;import java.util.*;public class day01_list {public static void main(String[] args) {// <Integer> 这个尖括号表示的是 Java 的泛型(Generics)// 泛型是 Java 5 引入的一项特性,它允许你在 类、接口和方法 中使用类型参数,从而使代码更具通用性和类型安全性// List 是一个接口,代表一个有序的集合,其中可以包含重复的元素// <Integer> 是泛型参数,指定这个列表只能存储Integer类型的对象/*ArrayList是List接口的一个具体实现类,使用动态数组来存储元素不能使用new List<>(),因为List是一个接口,不能直接实例化,接口只是定义了一组方法,没有具体实现必须实例化一个 List 接口的实现类,比如 ArrayList、LinkedList钻石操作符 <> 是 Java 7 引入的一个简化语法,用于推断泛型参数类型。在右边使用 new ArrayList<>() 时,编译器会自动推断出这个 ArrayList 的类型参数是 Integer,因为左边明确指定了 List<Integer>*//*List 是一个接口,而 ArrayList 是这个接口的一个具体实现类。在编写代码时,使用接口类型来声明变量,而用具体的实现类来实例化对象,这是面向对象编程中的一种最佳实践,称为“接口和实现分离”。多态性:通过使用接口类型,你可以利用多态性来处理对象。例如,你可以编写一个方法,它接收 List 类型的参数,这样这个方法就可以处理任何 List 的实现类(如 ArrayList、LinkedList、Vector 等)public void processList(List<Integer> list) {for (Integer number : list) {System.out.println(number);}}虽然 List 是一个接口,但在 Java 中,接口类型的变量可以引用任何实现这个接口的对象。这是因为接口定义了一组方法,而实现类提供了这些方法的具体实现。*/// 多态性List<Integer> arrayList = new ArrayList<>();List<Integer> linkedList = new LinkedList<>();processList(arrayList);processList(linkedList);/*使用接口类型声明变量的限制当你使用接口类型(例如 List)声明一个变量时,你只能调用接口中定义的方法然而,如果你需要调用实现类特有的方法,例如 ArrayList 的 ensureCapacity 方法,你就不能直接通过 List 类型的引用来调用。以下代码是非法的:*/List<Integer> list = new ArrayList<>();list.add(1);list.add(2);System.out.println(list.size()); // 这行代码是合法的,因为 add 和 size 是 List 接口中的方法// list.ensureCapacity(100); // 编译错误,因为 List 接口中没有 ensureCapacity 方法}public static void processList(List<Integer> list) {for (Integer number : list) {System.out.println(number);}}
}interface Animal {void eat();
}interface jiekou {void t();
}// 一个类只能继承一个父类(单继承),但可以实现多个接口(多实现)
// 一个接口可以继承多个其他接口(多继承)
interface Dog extends Animal, jiekou {}class ArrayList_use {/*Iterable<E> (接口)↑Collection<E> (接口) - 继承自 Iterable<E>↑List<E> (接口) - 继承自 Collection<E>↑AbstractCollection<E> (抽象类) - 部分实现 Collection<E>↑AbstractList<E> (抽象类) - 继承自 AbstractCollection 部分实现 List<E>↑ArrayList<E> (类) - 继承自 AbstractList<E> 并实现 List<E> 和 Collection<E>ArrayList 类除了实现 List 接口的方法外,还提供了一些独有的方法。这些方法在 List<> list 中无法直接使用:clone(): ...trimToSize(): 调整 ArrayList 的容量大小,使其等于当前列表的大小,减少内存使用。ensureCapacity(int minCapacity): 增加 ArrayList 的容量,确保它至少可以容纳指定数量的元素。*/// 数组可以包含基本数据类型和引用类型,ArrayList只能包含引用类型// 数组的大小在定义后不可以调整大小。ArrayList是基于动态数组实现的,可以通过内部扩容自动调整容量public static void main(String[] args) {// 三种构造方法List<Integer> list0 = new ArrayList<>(); // 构造一个初始容量为 10 的空列表list0.add(1);System.out.println(list0.size());List<Integer> list1 = new ArrayList<>(0); // 直接指定初始大小list1.add(1);System.out.println(list1.size());List<Integer> existingList = Arrays.asList(1, 2, 3);  // 返回一个ArrayList对象List<Integer> list2 = new ArrayList<>(existingList);  // 使用现成的list来构建System.out.println(list2.size());Set<Integer> existingSet = new HashSet<>(Arrays.asList(1, 2, 3, 4));List<Integer> list3 = new ArrayList<>(existingSet);  // 使用现成的set来构建System.out.println(list3.size());// 尾插数据时速度是o(1)// 非尾插数据,会涉及元素的移动,在添加元素时会涉及到扩容的问题。// 超出初始长度时,会创建新的数组,将原数组数据赋值到新数组中。扩容:原来数组的大小+原来数组的一半(1.5倍)// ArrayList 是线程不安全的:// 线程不安全表示当多个线程同时访问一个对象时,如果没有适当的同步机制,可能会导致数据不一致或其他错误。// 在 ArrayList 中,多个线程同时修改列表可能会导致未定义的行为,包括但不限于数据丢失、重复或异常// 1. addList<String> list4 = new ArrayList<>(Arrays.asList("A", "B", "C"));list4.add("D");System.out.println(list4);list4.add(1, "X");System.out.println(list4);// 2. addAllList<String> temp = Arrays.asList("A", "B", "C");list4.addAll(temp);System.out.println(list4);list4.addAll(1, temp);System.out.println(list4);// 3. forEachlist4.forEach(System.out::println);// 4. clearlist4.clear();System.out.println(list4);// 5. clone// clone() 方法是 ArrayList 类特有的方法,而不是 List 接口的方法。// 因此,如果你需要克隆一个 ArrayList,你需要确保你的变量类型是 ArrayList 而不是 List。ArrayList<String> existingListTempClone = new ArrayList<>(Arrays.asList("A", "C"));ArrayList<String> clonedArrayList = (ArrayList<String>) existingListTempClone.clone();List<String> cloneList = (List<String>) existingListTempClone.clone();// 修改克隆list的对象看看会不会对原来造成影响// 6. setcloneList.set(0, "xiugai");// 7. getSystem.out.println(cloneList.get(0));System.out.println(existingListTempClone.get(0));// 8.containsSystem.out.println(cloneList.contains("xiugai"));// 9. containsAllList<String> containsList0 = new ArrayList<>(Arrays.asList("xiugai", "C"));List<String> containsList1 = new ArrayList<>(Arrays.asList("xiugai", "X"));System.out.println(cloneList.containsAll(containsList0));System.out.println(cloneList.containsAll(containsList1));// 10. indexOfList<Integer> indexOfList = new ArrayList<>(Arrays.asList(1, 2, 3));System.out.println(indexOfList.indexOf(2));// 11. removeAllList<Integer> removeList = new ArrayList<>(Arrays.asList(2, 3, 2));indexOfList.removeAll(removeList);// 12. removeList<Integer> removeList1 = new ArrayList<>(Arrays.asList(1, 2, 3));removeList1.remove(0);removeList1.remove(Integer.valueOf(2));  // Integer.valueOf(2) 将整数 2 包装为 Integer 对象System.out.println(removeList1);// 13. size// 14. isEmpty// 15. subList// 16. toArray// 17. toString// 18. lastIndexOfList<Double> doubleList = new ArrayList<>(Arrays.asList(1.0, 5.0, 2.0, 2.0));System.out.println(doubleList.size());System.out.println(doubleList.isEmpty());System.out.println(doubleList.subList(1, 2));System.out.println(doubleList.toArray()[2]);System.out.println(doubleList.toString());System.out.println(doubleList.lastIndexOf(Double.valueOf(2.0)));}
}class LinkedList_use {/*Iterable<E> (接口)↑Collection<E> (接口) - 继承自 Iterable<E>↑List<E> (接口) - 继承自 Collection<E>↑AbstractCollection<E> (抽象类) - 部分实现 Collection<E>↑AbstractList<E> (抽象类) - 继承自 AbstractCollection 部分实现 List<E>↑AbstractSequentialList<E> (抽象类) - 继承自 AbstractList<E>↑LinkedList<E> (类) - 继承自 AbstractSequentialList<E> 并实现 List<E>, Deque<E>, Queue<E>, Collection<E>Iterable<E> (接口)↑Collection<E> (接口) - 继承自 Iterable<E>↑Queue<E> (接口) - 继承自 Collection<E>↑Deque<E> (接口) - 继承自 Queue<E>  Double Ended QueueLinkedList 类除了实现 List 接口的方法外,还实现了 Deque 接口,因此提供了一些双端队列(Deque)和队列(Queue)的特有方法。这些方法在 List<> list 中无法直接使用:void addFirst(E e)void addLast(E e)boolean offerFirst(E e)  // 头部插入元素,返回是否成功,成功为 true,失败为 falseboolean offerLast(E e)E removeFirst()E removeLast()E pollFirst()  // 检索并删除此列表的第一个元素,如果此列表为空则返回nullE pollLast()E getFirst()E getLast()E peekFirst()  // 返回头部元素,不删除E peekLast()LinkedList也是多线程环境下不安全*/LinkedList<Integer> list = new LinkedList<>();}/*** ArrayList和LinkedList** 数据结构* ArrayList底层是动态数组,在空间中是一段连续的内存* LinkedList底层是链表,内存不连续,对内存要求低。** 空间利用:* ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间* LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间** 尾插数据:对ArrayList和LinkedList而言,在列表末尾增加一个元素时间复杂度都是 o(1)。* 对ArrayList来说,尾插速度非常快,但是会涉及到一个扩容的问题,会进行大量的复制操作。* 而对LinkedList而言,使用了链表结构,不需要维护大小,但是他每次添加需要新建entry对象,进行赋值操作。* 总得来说如果不涉及到扩容的问题,ArrayList的尾插会更快一些。** 非尾插:* 在ArrayList的中间插入或删除一个元素会导致列表中剩余的元素都会被移动,因此效率较低,插入位置越靠前,需要复制调整的元素也越多,效率也就越慢。* LinkedList的非尾插,首先要通过循环找到需要插入的位置。如果此位置处于前半段,则从前往后找;若其位置处于后半段,则从后往前找。所以在靠前和靠后的位置插入非常高效,但是在拥有大量元素的情况下,在链表的中间插入元素效率很低。(首尾复杂度为o(1),其余为o(n),整体来说还是o(n))** 当操作是在一列数据的后面添加数据而不是在前面或中间,并且需要随机地访问其中的元素时,使用ArrayList会有更好的性能。* 当操作是在一列数据的前面或中间添加或删除数据,并且按照顺序访问其中的元素时,就应该使用LinkedList了。*/
class TestArrayListAndLinkedList {public static void main(String[] args) {List<String> arraylist = new ArrayList<>();int listSize = 100;for(int i=0; i<listSize; i++){arraylist.add("初始数据");}System.out.println("ArrayList插数据用时:" + insert(arraylist));List<String> linkedList = new LinkedList<>();for(int i=0; i<listSize; i++){linkedList.add("初始数据");}System.out.println("LinkedList插数据用时:" + insert(linkedList));}// index=10插入:// ArrayList数据用时:3// LinkedList数据用时:0// list.size()/2插入// ArrayList插数据用时:4// LinkedList插数据用时:1// list.size()-10// ArrayList插数据用时:4// LinkedList插数据用时:2// 尾插:// ArrayList插数据用时:3//LinkedList插数据用时:0//插入数据,分别在头部、中间、尾部(四种插入位置:10、list.size()/2、list.size()-10、尾插)public static Long insert(List<String> list){long startTime = System.currentTimeMillis();int insertNum = 500;for (int i=0; i<insertNum; i++){list.add(10,"数据"+i);  // 中间靠前部分插入
//            list.add(list.size()/2,"数据"+i);  //中间插入
//            list.add(list.size()/2+10,"数据"+i);  //中间靠后插入
//            list.add("数据"+i);  // 尾插}long endTime = System.currentTimeMillis();return endTime-startTime;}}

接口和抽象类是 Java 编程语言中用于实现抽象的两种主要机制。它们允许你定义类的骨架和行为规范,而不提供具体的实现。

接口(Interface)

概述
接口是一个完全抽象的类,它只包含方法的声明(没有方法体)和常量。接口用于定义一组方法,这些方法必须由实现接口的类提供具体的实现。

特点

  • 完全抽象:接口中的方法默认是 public 和 abstract,不能有方法体(直到 Java 8 引入默认方法和静态方法)。
  • 多重继承:一个类可以实现多个接口,打破了 Java 单继承的限制。
  • 变量:接口中的变量默认是 public、static 和 final。
  • 默认方法和静态方法:从 Java 8 开始,接口可以包含默认方法(有方法体)和静态方法。
  • 私有方法:从 Java 9 开始,接口可以包含私有方法,这些方法只能在接口中调用。

示例

public interface Animal {void eat();  // 抽象方法,默认是 public abstractvoid sleep();// 默认方法default void breathe() {System.out.println("Breathing...");log("breathe");}// 静态方法static void info() {System.out.println("Animal Interface");logStatic("info");}// 私有方法private void log(String activity) {System.out.println("Logging activity: " + activity);}// 私有静态方法private static void logStatic(String activity) {System.out.println("Logging static activity: " + activity);}
}

抽象类(Abstract Class)

抽象类在 Java 中是用于定义类的骨架的类,包含具体方法(有方法体)和抽象方法(没有方法体)。抽象类不能被实例化,必须被子类继承,并且,如果子类不是抽象类,那么子类必须实现所有抽象方法。

  • 抽象方法和具体方法:抽象类可以包含抽象方法和具体方法。抽象方法没有方法体,具体方法有方法体。子类必须实现抽象方法,或者自身也声明为抽象类。
  • 成员变量:抽象类可以包含成员变量,可以使用各种访问修饰符(public、protected、private)。
  • 构造方法:抽象类可以有构造方法,但不能用来创建对象实例。构造方法通常用于初始化类的成员变量。
  • 继承:一个类只能继承一个抽象类(单继承),但抽象类可以被多个类继承。
  • 实现接口:抽象类可以实现接口,并且不需要实现接口中的所有方法。子类可以选择实现剩余的方法。
public abstract class Animal {private String name;  // 成员变量// 构造方法public Animal(String name) {this.name = name;}// 抽象方法public abstract void eat();public abstract void sleep();// 具体方法public void breathe() {System.out.println(name + " is Breathing...");}// 获取名称的方法public String getName() {return name;}
}

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

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

相关文章

网页如何快速被收录?

其实就是要要吸引搜索引擎爬虫更快地抓取你的网页&#xff0c;想让爬虫爬取网页&#xff0c;首要做的自然是创建并提交站点地图。站点地图是搜索引擎了解你网站结构的重要工具。它可以帮助爬虫更快地发现和抓取你网站上的所有重要页面。通过Google Search Console提交站点地图&…

网络编程常识

网络编程常识 网络编程常识一、 OSI七层模型对应 TCP/IP四层模型二、TCP协议 最后 网络编程常识 一、 OSI七层模型对应 TCP/IP四层模型 OSI七层模型TCP/IP四层模型应用层表示层会话层应用层传输层传输层网络层网络层数据链路层物理层网络接口层 物理层&#xff1a;主要定义物…

深度学习在目标检测中的革命性应用与进展

目标检测是计算机视觉领域的核心任务之一&#xff0c;它旨在从图像或视频中识别和定位感兴趣的目标。深度学习的出现极大地推动了目标检测技术的发展&#xff0c;提高了检测的准确性和效率。本文将详细探讨深度学习在目标检测中的应用&#xff0c;包括关键技术、算法进展、实际…

python编程题3

1. 将一个文件中的所有英文字母转换成大写&#xff0c;复制到另一文件中。 fiopen("ex01.py",r) foopen("f2.txt",w) for line in fi:lineline.upper()fo.write(line) fi.close() fo.close() 2. 将一个文件中的指定单词删除后&#xff0c;复制到另一个文…

mysql lpad函数和rpad函数的用法

1、lpad函数 -从左至右填充 lpad( string, padded_length, [ pad_string ] ) string 准备被填充的字符串&#xff1b; padded_length 填充之后的字符串长度&#xff0c;也就是该函数返回的字符串长度&#xff0c;如果这个数量比原字符串的长度要短&#xff0c;lpad函数将会把字…

Perl与CGI脚本:入门指南到Web页面生成

Perl是一种功能强大的编程语言&#xff0c;广泛用于文本处理和系统管理任务。它也是早期Web开发中用于编写CGI脚本的流行选择之一。CGI&#xff08;Common Gateway Interface&#xff09;是一个标准&#xff0c;定义了Web服务器与执行在服务器上的程序之间的交互方式。本文将详…

MobPush REST API的推送 API之批量推送

调用验证 详情参见 REST API 概述的 鉴权方式 说明。 频率控制 详情参见推送限制策略的 接口限制 说明。 调用地址 POST http://api.push.mob.com/v3/push/createMulti 推送对象 以 JSON 格式表达&#xff0c;表示一条推送相关的所有信息 字段类型必须说明pushWorkobje…

用JSZip,FileSaver 有现成cdn的http图片或者文件地址,弄成压缩包导出,解决如果文件名字都是一样的只导出一个图片或文件的方法

第一步先处理重名的数据 &#xff0c; 解决方法 &#xff1a;将相同名字的图片或文件后面加后缀数字作为区分 let arr [{name:图片一,url:http://cdn}, {name:图片一,url:http://cdn}, {name:图片二,url:http://cdn}]; // 创建一个对象来跟踪已经遇到的名称和它们的计数 le…

6. 较全的Open3D点云数据处理(python)

注意&#xff1a;以下内容来自博客爆肝5万字❤️Open3D 点云数据处理基础&#xff08;Python版&#xff09;_python 点云 焊缝-CSDN博客&#xff0c;这篇博客写的全且详细&#xff0c;在这里是为了记笔记方便查看&#xff0c;并非抄袭。 1.点云的读写 代码如下&#xff1a; …

ARM功耗管理软件之软件栈及示例

安全之安全(security)博客目录导读 思考:功耗管理软件栈及示例?WFI&WFE?时钟&电源树?DVFS&AVS?

php对接快手券码,扫码核销

快手本地生活-开放平台&#xff1a;https://open.kwailocallife.com/docs/dev 快手本地生活-商家中心&#xff1a;https://lbs.kuaishou.com/ll/merchant/login 实现功能&#xff1a;对接快手券码&#xff0c;实现在快手上购买券码&#xff0c;然后在自己开发的app上扫码核销&…

ubuntu22.04速装中文输入法

附送ubuntu安装chrome wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb sudo dpkg -i google-chrome-stable_current_amd64.deb

磁盘扩容,新增磁盘

磁盘扩容 1.点击设置-硬盘-添加-按推荐添加磁盘 2.查看磁盘使用情况&#xff0c;未扩容之前&#xff0c;查看分区使用情况 [rootnode1 ~]# df -Th 文件系统 类型 容量 已用 可用 已用% 挂载点 devtmpfs devtmpfs 1.4G 0 1.4G …

干系人参与度矩阵

干系人参与度矩阵 干系人的定义干系人参与水平分类应用与策略总结 干系人参与度矩阵是用于评估项目干系人当前参与水平与期望参与水平之间差异的工具。以下是对干系人参与度矩阵的详细解释&#xff1a; 干系人的定义 在项目管理中&#xff0c;干系人指的是那些积极参与项目&am…

python中pip换源

目录 1. 背景2. Python 的 pip 换源2.1 临时换源&#xff08;命令行中使用参数&#xff09;2.2 永久换源&#xff08;修改配置文件&#xff09;2.2.1 Windows系统2.2.2 Linux/macOS系统 2.3 使用 pip-config 命令换源&#xff08;Linux/macOS 特定&#xff09; 3. 常用的 PyPI …

探索WebKit的革新之旅:HTML5新特性的卓越处理

标题&#xff1a;探索WebKit的革新之旅&#xff1a;HTML5新特性的卓越处理 摘要 WebKit作为许多流行浏览器的渲染引擎&#xff0c;包括Safari、Chrome和Epiphany&#xff0c;它在处理HTML5新特性方面扮演了重要角色。HTML5引入了一系列新特性&#xff0c;旨在改善网络应用的性…

Java IO: 使用 `FileInputStream` 和 `FileOutputStream` 进行文件操作

在 Java 中&#xff0c;文件 I/O 操作是常见的任务。FileInputStream 和 FileOutputStream 是用于读取和写入文件的基础类&#xff0c;适用于处理二进制数据。本文将介绍如何使用 FileInputStream 和 FileOutputStream&#xff0c;并提供具体的示例代码。 FileInputStream 类概…

深入分析 Android BroadcastReceiver (七)

文章目录 深入分析 Android BroadcastReceiver (七)1. 高级应用场景1.1 示例&#xff1a;动态权限请求1.2 示例&#xff1a;应用内通知更新 2. 安全性与性能优化2.1 示例&#xff1a;设置权限防止广播攻击2.2 示例&#xff1a;使用 LocalBroadcastManager2.3 示例&#xff1a;在…

三分钟给AI Agent应用对话增加人类情感!

点击下方“JavaEdge”&#xff0c;选择“设为星标” 第一时间关注技术干货&#xff01; 免责声明~ 任何文章不要过度深思&#xff01; 万事万物都经不起审视&#xff0c;因为世上没有同样的成长环境&#xff0c;也没有同样的认知水平&#xff0c;更「没有适用于所有人的解决方案…

[算法]——堆排序(C语言实现)

简单的介绍一下用堆排序的算法对整形数据的数据进行排序。 一、堆的概念 堆是具有下列性质的完全二叉树&#xff1a;每个结点的值都大于或等于其左右孩子节点的值&#xff0c;称为大顶堆&#xff1b;或者每个结点的值都小于或等于其左右孩子结点的值&#xff0c;称为小顶堆。 …