详解Java中集合的List接口实现的ArrayList方法 | Set接口实现的HashSet方法

集合的概念

      当我们需要保存一组一样(类型相同)的元素的时候,我们应该使用一个容器来存储,数组就是这样一个容器。

数组的特点:     

      数组是一组数据类型相同的元素集合;

      创建数组时,必须给定长度,而且一旦创建长度不能改变;

      一旦数组装满元素,就需要创建一个新的数组,将元素复制过去;

数组的局限:

        如果装满了,就需要数组复制;

        当我们需要从数组中删除或添加一个元素,需要移动后面的元素;

集合的作用:

       在开发实践中,我们需要一些能够动态增长长度的容器来保存我们的数据,java中为了解决数据存储单一的情况,java中就提供了不同结构的集合类,可以让我们根据不同的场景进行数据存储的选择,如Java中提供了 数组实现的集合,链表实现的集合,哈希结构,树结构等。

分类

单列集合:一次放进去一个值 ( 对象 )

Collection接口:定义了单列集合共有的方法,其子接口Set和List分别定义了存储方式

List:可以有重复元素

Set:不可以有重复元素

双列集合: 键    值

集合API

集合体系概述: Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。

List 接口及实现类

概念:List继承了Collection接口,有三个实现的类,分别是:

ArrayList       数组列表

LinkedList     链表列表

Vector            数组列表 (是线程安全的)

1.  ArrayList

         ● 底层有一个数组,可以动态扩展数组长度,并提供了一系列方法操作。

特点: 查询快,在中间增加 / 删除慢

注意:集合容器类中默认可以添加Object类型,但是一般建议一个集合对象只保存同一种类型,若保存多个类型后期处理时涉及类型转换问题;所以我们可以通过泛型来加以控制。

  
         ● 泛型:声明类型时可以自定义参数类型
                      ArraysList  <E>
ArrayList的常用方法:

ArrayList<String> arrayList = new ArrayList();arrayList.add("a");arrayList.add("b");arrayList.add("c");arrayList.add(3,"a");arrayList.remove("a");  //根据内容删除匹配的第一个元素,返回值为booleanarrayList.remove(1);    //删除并返回指定位置的元素arrayList.get(1);         //获取指定位置的元素arrayList.set(1,"X");     //替换并返回指定位置的元素arrayList.clear();        //清空集合中的元素arrayList.isEmpty();      //判断集合元素是否为空arrayList.contains("c");  //判断是否包含指定元素arrayList.size();         //返回集合中元素个数

2.  LinkedList

● 底层是一个链表结构,查询效率低,但增加 / 删除元素快

LinkedList中方法及功能和ArrayList中的方法大致相同,只不过LinkedList中多了关于队列相关的操作方法。

3.  Vector

和ArrayList一样,底层也是数组实现,不同的是Vector的方法默认加了锁,线程是安全的。

List接口集合迭代

List集合遍历方式有四种:

●  1.  for循环遍历          ● 2.  增强for循环遍历   

        //List集合遍历方式1:for循环for (int i = 0; i < arrayList.size(); i++) {if ("a".equals(arrayList.get(i))){arrayList.remove("a");//允许修改集合元素i--;            // 要注意索引的变化与元素位置的移动}}System.out.println(arrayList);System.out.println("----------------");//List集合遍历方式2:增强for循环for (String s:arrayList) {System.out.println(s);   //不能修改集合元素}

 3.  迭代器遍历 (Iterator)

        //List集合遍历方式3:使用迭代器遍历//获得集合对象的迭代器对象Iterator<String> it = arrayList.iterator();while(it.hasNext()){String s = it.next();//获取下一个院系if (s.equals("a")) {it.remove();  //使用迭代器对象删除元素}}System.out.println(arrayList);

4.  ListIterator迭代器:

public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList();arrayList.add("a");arrayList.add("b");arrayList.add("c");arrayList.add("d");/*ListIterator迭代器只能对List接口下的实现遍历ListIterator(index)可以从指定位置开始向前向后遍历*/ListIterator<String> listIterator= arrayList.listIterator(arrayList.size());while(listIterator.hasPrevious()){System.out.println(listIterator.previous());//逆序遍历}}

Set接口

● Set接口也继承了Collection接口,Set中所储存的元素是不重复的,但是是无序的,Set中的元素没有索引。

Set接口的实现类

● HashSet 

● 1. HashSet类中的元素不能重复

 public static void main(String[] args) {HashSet set =new HashSet<>();set.add("a");set.add("a");set.add("b");set.add("c");    //元素是不重复的System.out.println(set);}

● 2. HashSet类中的元素是无序的 

public static void main(String[] args) {HashSet set =new HashSet<>();set.add("c");set.add("s");set.add("x");set.add("d");    //元素是无序的System.out.println(set);set.remove("s");//没有索引,只能根据内容遍历set.iterator();//没有索引,要用迭代器遍历}

 HashSet在添加元素时,是如何判断元素重复的?          *  重点  * 

在底层会先调用hashCode(),注意,Object中的hashCode()返回的是对象的地址,此时并不会调用;此时调用的是类中重写的hashCode(),返回的是根据内容计算的哈希值,遍历时,会用哈希值先比较是否相等,会提高比较的效率;但哈希值会存在问题:内容不同,哈希值相同;这种情况下再调equals比较内容,这样既保证效率又确保安全。

例:

这是错误写法,此时默认调用的是Object类中hashCode( ),返回对象地址

import java.util.HashSet;
import java.util.Objects;public class Student {private String name ;private String num;public Student(String name, String num) {this.name = name;this.num = num;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", num='" + num + '\'' +'}';}public static void main(String[] args) {HashSet<Student> set = new HashSet<>();Student s1 = new Student("小王1","10001");Student s2 = new Student("小王2","10002");Student s3 = new Student("小王3","10003");Student s4 = new Student("小王1","10001");set.add(s1);set.add(s2);set.add(s3);set.add(s4);System.out.println(set);}}

 正确写法应该是,在Student类中重写hashCode()和equals()

package Demo;import java.util.HashSet;
import java.util.Objects;public class Student {private String name ;private String num;@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return num.equals(student.num);}@Overridepublic int hashCode() {return Objects.hash(num);}public Student(String name, String num) {this.name = name;this.num = num;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", num='" + num + '\'' +'}';}public static void main(String[] args) {HashSet<Student> set = new HashSet<>();Student s1 = new Student("小王1","10001");Student s2 = new Student("小王2","10002");Student s3 = new Student("小王3","10003");Student s4 = new Student("小王1","10001");set.add(s1);set.add(s2);set.add(s3);set.add(s4);System.out.println(set);}}

这样就能避免重复了(此图是s1,s4重复,但只输出s1)

补充:如何快速生成hashCode()和equals()的重写方法?

右键选择Generate,选择equals()and hashCode(),选择重写的属性。

● TreeSet

......敬请期待^_^

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

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

相关文章

Stable Diffusion 模型分享:3D Animation Diffusion(3D动漫)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 3D Animation Diffusion 是 Lykon 大神的 3D 动漫模型。 作者述&#xff1a;在迪士尼、皮…

SPI相关知识总结

一、SPI 1.1SPI概念及通讯方式 SPI&#xff1a;串行外设设备接口&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线 2.1 SPI框图 1.3.数据发送与接收流程 1.4 SPI工作模式 1&#xff09;时钟极…

【OpenGL编程手册08】 摄像机

一、说明 前面的教程中我们讨论了观察矩阵以及如何使用观察矩阵移动场景&#xff08;我们向后移动了一点&#xff09;。OpenGL本身没有摄像机(Camera)的概念&#xff0c;但我们可以通过把场景中的所有物体往相反方向移动的方式来模拟出摄像机&#xff0c;产生一种我们在移动的感…

LeetCode 2673. 使二叉树所有路径值相等的最小代价【贪心】1917

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

附录:jdk安装及环境变量的配置

jdk的安装 JDK &#xff08;Java Development Kit&#xff09;称为 Java 开发包或 Java 开发工具&#xff0c;是一个编写 Java 的 Applet 小程序和应用程序的程序开发环境。 下载jdk 在 oracle 官网中下载 jdk https://www.oracle.com/ 点击 JDK 下载自己需要的 JDK 版本&…

《UE5_C++多人TPS完整教程》学习笔记27 ——《P28 项目资产(Assets for The Project)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P28 项目资产&#xff08;Assets for The Project&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译…

BUUCTF---[ACTF2020 新生赛]BackupFile1

1.题目描述 2.题目提示backup file &#xff0c;是备份文件的意思。点开链接&#xff0c;页面提示 3.查看源码没有什么有用信息&#xff0c;也没有登录界面&#xff0c;所以也不会用到蚁剑链接来找备份文件&#xff0c;所以大概率就是通过构造playload来查找备份文件。 4.备份…

rust学习(tokio future分析)

自己编写一个impl future来看一下Tokio的是如何实现的。 第一步&#xff1a; 代码&#xff1a; struct TExecuteTask {count:u32 }impl Future for TExecuteTask {type Output ();fn poll(self: Pin<&mut Self>, cx: &mut Context<_>) -> Poll<S…

Pygame教程03:文本显示+字体加载+transform方法

------------★Pygame系列教程★------------ Pygame教程01&#xff1a;初识pygame游戏模块 Pygame教程02&#xff1a;图片的加载缩放旋转显示操作 Pygame教程03&#xff1a;文本显示字体加载transform方法 Pygame教程04&#xff1a;draw方法绘制矩形、多边形、圆、椭圆、弧…

Java8,函数式编程应用:

持续更新中&#xff1a; 函数式(Functional)接口 什么是函数式(Functional)接口 只包含一个抽象方法的接口&#xff0c;称为函数式接口。 你可以通过 Lambda 表达式来创建该接口的对象。&#xff08;若 Lambda 表达式 抛出一个受检异常(即&#xff1a;非运行时异常)&#xff0c…

Crossbar阵列的电路结构及其基本原理

忆阻器Crossbar阵列是一种先进的神经网络硬件实现技术&#xff0c;它利用忆阻器的物理特性来模拟神经网络中的突触连接&#xff0c;为人工智能和机器学习应用提供了一种高效、低能耗的计算平台。本文将深入探讨忆阻器Crossbar阵列的基本原理及其在Read&#xff08;读取&#xf…

运维随录实战(2)之k8s部署应用

一, 创建.gitlab-ci.yml文件 架构流程 文件内容 stages: #设置流水线模版- build # 编译- source2img- deploy # 发布variables: # 设置全局变量MAVEN_PATH: .m2MAVEM_IMAGE: maven:3.8.5-openjdk-17-slim # maven 打包使用的镜像MAVEN_CLI_OPTS: "-s $MAVEN_PATH/set…