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

中object转为list集合_快速带你梳理Java单列集合之Collection


1. 集合概述

由于我们开发过程中,难以避免不去操作数据,操作对象就有可能对数据进行存储,存储数据的方式多种多样,之前我们都是将数据存储在数组中,但数组的特点是长度固定不可改变的,这样就不适合用于存储变化(个数的变化)的数据。因此,Java提供一种容器用于存储数据,这个容器就叫做集合


2. 集合和数组的区别

数组:

  1. 长度固定
  2. 可以存储基本数据类型,也可以存储引用数据类型
  3. 存储的数据类型必须要一致(比如说创建一个int类型的数组,它就只能存整数,不能存double或者String类型等)

集合:

  1. 长度可变
  2. 只能存储引用数据类型
  3. 可以存储不同类型的对象。(可以存int、String、double等)

3. 集合的体系:

9f86138d085f03197cd4d120afdbeb6e.png

4.下面看一下各成员特点

|- - List: 有序(序指的是存和取得顺序一致,怎么样存就怎么样取),元素可以重复

|- - - - - - - ArrayList: 底层数据结构是数组,查询快,增删慢,线程不安全,效率高

|- - - - - - - Vector: 底层数据结构是数组,查询快,增删慢,线程安全,效率低

|- - - - - - - LinkedList: 底层数据结构是链表,查询慢,增删快,线程不安全,效率高

|- - Set: 无序,元素不可以重复

|- - - - - - - HashSet: 底层数据结构是哈希表,线程不安全,效率高

|- - - - - - - TreeSet: 底层数据结构是二叉树,线程不安全,效率高


5. Collection接口中的常用方法

44a0b034da1b227f82e1bea1b95a0b3d.png

注:Collection是一个根接口,继承它的子类或者子接口都能使用它的方法


6. List集合特有的方法

bf861646cbc641121778531f4c52bf1d.png

7. ArrayList

ArrayList是List接口下的一个实现类之一,也是最常用的一个集合,由于它的底层是数组结构实现的,因此可以看成是一个长度可变的数组,下面介绍关于ArrayList的常见使用

public class Demo { public static void main(String[] args) { //定义一个ArrayList集合 ArrayList arrayList = new ArrayList();  arrayList.add("你好"); //添加元素 arrayList.add(20); arrayList.add(20); //添加了重复元素 arrayList.set(0, "hello"); //修改了索引为0的元素 int size = arrayList.size(); //获取集合的大小  System.out.println("集合的大小为:"+size); //输出:集合的大小为:3 System.out.println(arrayList.get(2)); //输出:20 System.out.println(arrayList); //输出:[hello, 20, 20] } }

7.1 集合的遍历

7.1.1.通过集合转数组,然后再对数组进行遍历

Collection c = new ArrayList(); c.add("abc"); c.add("abcd"); c.add("abcde"); Object[] array = c.toArray(); //将集合转为数组 for(int i=0; i

7.1.2.通过get()和size()方法结合(仅仅适用于Collection的子接口List接口)

//定义一个ArrayList集合 ArrayList arrayList = new ArrayList(); arrayList.add(10); arrayList.add(50); arrayList.add("你好"); arrayList.add(8);  for (int i = 0; i < arrayList.size(); i++) { Object obj = arrayList.get(i); //根据索引获取值,在此返回的是Object数据类型 System.out.print(obj + " "); }

7.1.3.通过迭代器实现(适用于所有集合) (下面将会介绍)

//定义一个ArrayList集合 ArrayList arrayList = new ArrayList(); arrayList.add(10); arrayList.add(50); arrayList.add("你好"); arrayList.add(8);  //第一步:创建迭代器对象 Iterator iterator = arrayList.iterator(); //第二步:通过hasNext()方法判断迭代器中是否有元素 while (iterator.hasNext()) { //第三步:通过next()方法获取元素 Object object = iterator.next(); System.out.print(object + ""); }}

7.1.4.通过增强for循环遍历(适用于所有集合和数组) (推荐使用)

注意:增强for只能操作集合和数组

定义格式:

for(数据类型 临时变量名 : 集合或者数组){

}

例如定义了一个集合ArrayList list = new ArrayList(); 此处的集合如不指定数据类型,默认为Object类型,则它的增强for格式就为:

for(Object obj:list) {

}

//定义一个ArrayList集合 ArrayList arrayList = new ArrayList(); arrayList.add(10); arrayList.add(50); arrayList.add("你好"); arrayList.add(8);  //增强for进行遍历 for (Object object : arrayList) { System.out.print(object + " "); }

7.2 迭代器

7.2.1 何为迭代器

迭代器是从集合中取出元素的一种标准方式,我们取出任何集合中的元素都可以按照这个标准来获取,主要遍历Collection集合中的元素。迭代是取出集合中元素的一种方式

7.2.2 原理

因为多种集合的数据结构不同,所以存储方式不同,因此取出方式也不同。这个时候,我们就把判断和获取功能定义在了一个接口中,将来,遍历哪种集合的时候,只要该集合内部实现这个接口即可(由于集合内部已经实现了该接口,因此直接使用即可,无需我们手动实现 )

7.2.3 使用方式

通过集合对象调用iterator()方法便可获得一个且迭代器对象Iterator,然后再通过hasNext()方法判断是否含有元素,最后通过next()方法获取集合中的元素。(使用示例见上文7.1集合遍历中的第三种方法)

7.2.4 常见问题

在我们对集合进行遍历的时候,有时候可能会对集合进行删除或者增加元素。但当我们使用Iterator对集合进行遍历的同时进行增删操作时,会出现一个异常,那就是并发修改异常 ConcurrentModificationException。 但要是我们硬是要在迭代的时候对元素进行增删操作的时候该肿么办呢?这时就有一个办法解决啦!这个办法就是通过集合对象获取Iterator的子接口ListIterator (例如:ListIterator iterator = arrayList.listIterator(); )

7.2.5 Iterator 和 ListIterator的区别

1、Iterator是ListIterator的父接口

2、Iterator是Collection集合的公共的取出容器中元素的方式,对于List,Set都通用。而ListIterator是List集合的特有的取出元素的方式

3、Iterator中只具备hasNext(),next(),remove()方法,可以删除被遍历到的元素ListIterator中具备对遍历到的元素进行增(add)删(remove)改(set)查(next)的方法,可以对元素逆向遍历previouse相对于next,hasPreviouse相对于hasNext(用的很少)

7.2.6 Iterator 和 ListIterator的成员方法

07ff523961b231985c3a64c359f0c1de.png

8. LinkedList

LinkedList底层实现是链式结构,它的特点是增加删除元素快,查询元素慢。就像人们手牵手连在一起排成一条队列,每个人就可以看做一个元素,当有一个人想进入或者退出队列的时候,只是旁边两人断开手就行了,要是想查询某人处于什么位置,只能从开头或者默认一个一个地查询下去,这样效率就大大下降了。

8.1 特有的方法

aa16628ef6b6b2938be32aaccb8658da.png

8.2 使用示例

import java.util.LinkedList;public class LinkedListDemo { public static void main(String[] args) { LinkedList list = new LinkedList(); list.addFirst("java01"); list.addFirst("java02"); list.addFirst("java03"); list.addFirst("java04");  System.out.println(list); System.out.println(list.getFirst()); while (!list.isEmpty()) { System.out.println(list.removeLast()); } }}

9. 泛型

9.1 何为泛型

泛型是一种把明确类型的工作放在了创建对象或者调用方法时候才去明确的特殊的类型,泛型就相当于一个预定义类型

9.2 好处

把系统运行期间的异常提前到了编译期间,提高了安全性优化了程序设计,不需要再做强壮了

9.3 缺点

泛型只能传入引用类型,不能传入基本类型,如需要传入基本类型只能传入基本类型对应的包装类类型

包装类表如下:

47e099f01ff4595631dddc4e659862e4.png

9.4 泛型的使用

泛型可以定义在类中,方法中和接口中。下面介绍在创建对象时使用泛型和不使用泛型的区别。

不使用泛型时:

//定义一个ArrayList集合,没有指定泛型,默认为Object类型 ArrayList arrayList = new ArrayList(); arrayList.add("元素1"); arrayList.add("元素2"); arrayList.add("元素3");  for (int i = 0; i < arrayList.size(); i++) { //由于ArrayList默认为Object类型,因此在不加泛型的时候获取元素需要强转 String string = (String) arrayList.get(i); System.out.print(string + " "); }

使用泛型:

//定义一个ArrayList集合,指定泛型为String类型 ArrayList arrayList = new ArrayList(); arrayList.add("元素1"); arrayList.add("元素2"); arrayList.add("元素3"); //arrayList.add(2); 这里如果添加非String类型,会报错,因为已经指定泛型,从而将运行期间的异常提前到了编译期间  for (int i = 0; i < arrayList.size(); i++) { //由于在创建集合对象时已经给定泛型,因此在此不需要强转 String string = arrayList.get(i); System.out.print(string + " "); }

10. ArrayList练习

需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)

import java.util.ArrayList;import java.util.Iterator;/**  * 思路:想要对集合中的元素进去重,可以创建一个新的集合, 然后再遍历的时候判断新集合是否包含某个元素。 如果有了就不添加,否则就添加到新集合里面,最终得到的新集合就是没有重复元素的集合。  */ public class Demo {  public static void main(String[] args) { //定义一个ArrayList集合 ArrayList arrayList = new ArrayList(); //往集合中添加数据 arrayList.add("aa"); arrayList.add("cc"); arrayList.add("aa"); arrayList.add("bb"); arrayList.add("aa");  Iterator iterator = arrayList.iterator(); //获取迭代器 ArrayList newList = new ArrayList<>(); //创建一个新的集合 while (iterator.hasNext()) {  String string = iterator.next(); //获取就集合中的每个元素 if (!newList.contains(string)) { //如果新集合不包含该元素,就添加到新集合中 newList.add(string); }  } System.out.println(newList); //输出结果:[aa, cc, bb] }}

11. HashSet集合

HashSet集合存储的元素不会重复,并且存储顺序是不一致的。那么HashSet集合在添加元素时是如何保证元素不会重复添加呢?其实它是通过两个方法来进行判断的。

11.1 保证不重复添加元素

  • hashCode()方法:首先通过调用对象的hashCode() 方法,返回一个int型的数据,这个数据就是哈希值。当存储两个元素时,会判断这两个元素的哈希值是否相同,如果不相同,就添加到集合中;否则会进行调用equals()方法
  • equals()方法:当两个元素的元素哈希值相等时,会调用此方法来判断两者的内容是否相同。不同则添加,相同就不添加到集合中

注意: 如果两个元素的哈希值不同,就不再需要调用equals方法了。

public class Demo {  public static void main(String[] args) { //1.创建一个HashSet集合,并指定为String泛型 HashSet hashSet = new HashSet<>(); //往集合中添加元素 hashSet.add("aa"); hashSet.add("bb"); hashSet.add("aa"); //添加重复元素 hashSet.add("cc");  //获取hashSet的迭代器对象 Iterator iterator = hashSet.iterator(); //对元素进行遍历 while (iterator.hasNext()) { String string = iterator.next(); System.out.print(string + " "); //输出:aa bb cc  } }}

11.2 HashSet主要方法

通过API可以看出HashSet的主要方法有:

b4e3ca82b1d2f8c649070dbe45613e5b.png

11.3 HashSet存储自定义对象

  • 需求:往HashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人。

首先定义一个Person实体类

/**  * 定义一个Person实体类(这里面的方法都是同快捷键生成的 Alt+Shift+S)  * 必须重写hashCode()方法和equals()方法,不然在添加对象进集合的时候不会去重  */ public class Person { /** 姓名*/ private String name; /** 年龄*/ private int age;  /** 无参构造方法*/ public Person() { super(); }  /** 有参构造方法*/ public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }  /**  * 重写hashCode()方法  */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } /**  * 重写equals()方法  */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Person other = (Person) obj; if (age != other.age) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }

然后再创建一个集合存储元素,并遍历

public class HashSetTest { public static void main(String[] args) { //创建一个集合,并只能存储Person对象 HashSet hs = new HashSet<>();  //往集合中添加了6个元素,有重复 hs.add(new Person("张三

相关文章:

  • 代码回到之前版本_代码版本控制及托管:我的最佳实践
  • springboot处理参数再转发请求_springBoot PUT请求接收不了参数的解决办法
  • 如何在EDUIS中导出ETL字幕模板_教大家Edius如何设置导出mp4格式视频
  • r语言和metawin_【R语言】关于ggcor包消息的更新
  • git maven 一键部署_Docker+Jenkins+Git+Maven实现Springboot项目自动化部署
  • 添加删除元素_蔡司:CALYPSO高级应用 | 指数交换与添加删除循环
  • 初中物理凸透镜成像动态图_只要看一眼,就能立刻知道凸透镜成像特点,中考物理必考送分题...
  • html5窗口最顶层_快速开发基于 HTML5 网络拓扑图应用——入门篇(一)
  • mime插件 node_【Node.js基础篇】(五)使用mime模块来响应css、js文件的请求
  • react前端封装接口弹出错误_在react项目中用es6封装ajax请求,组件中调用总是报错,求解?...
  • mysql5.7不能存储中文_解决Mysql5.7中文乱码的问题
  • mysql取字段中间字符串_sql 如何截取一个字段里某一字符串中间的字符?
  • mysql分区技术_高性能的MySQL(7)分区技术
  • mysql7.6.8安装教程_Centos7安装mysql8教程
  • rhel8安装配置mysql_Linux下Mysql8.0.19安装配置图文详解(Redhat centos 6.8)
  • [译]CSS 居中(Center)方法大合集
  • Angular数据绑定机制
  • css布局,左右固定中间自适应实现
  • Invalidate和postInvalidate的区别
  • JavaScript 基本功--面试宝典
  • magento2项目上线注意事项
  • vue.js框架原理浅析
  • 湖南卫视:中国白领因网络偷菜成当代最寂寞的人?
  • 如何学习JavaEE,项目又该如何做?
  • 想写好前端,先练好内功
  • 你对linux中grep命令知道多少?
  • 阿里云服务器购买完整流程
  • 昨天1024程序员节,我故意写了个死循环~
  • ​人工智能之父图灵诞辰纪念日,一起来看最受读者欢迎的AI技术好书
  • #传输# #传输数据判断#
  • (0)Nginx 功能特性
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (6)STL算法之转换
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (python)数据结构---字典
  • (二)PySpark3:SparkSQL编程
  • (简单) HDU 2612 Find a way,BFS。
  • (一)认识微服务
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (原創) 如何安裝Linux版本的Quartus II? (SOC) (Quartus II) (Linux) (RedHat) (VirtualBox)
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .gitattributes 文件
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .Net 垃圾回收机制原理(二)
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .NET开源的一个小而快并且功能强大的 Windows 动态桌面软件 - DreamScene2
  • .NET开源全面方便的第三方登录组件集合 - MrHuo.OAuth
  • /bin、/sbin、/usr/bin、/usr/sbin
  • /proc/stat文件详解(翻译)
  • @Autowired标签与 @Resource标签 的区别
  • @EnableWebMvc介绍和使用详细demo
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • []常用AT命令解释()