【Java集合】Collection 体系集合详解(ArrayList,LinkedList,HashSet,TreeSet...)

news/2024/11/19 12:36:08/

在这里插入图片描述

文章目录

  • 1. 概念
  • 2. 集合和数组的区别
  • 3. 集合的体系结构
  • 4. Collection父接口
  • 5. List 子接口
  • 6. List 实现类
    • 6.1 ArrayList 类
    • 6.2 Vector 类
    • 6.3 LinkedList 类
    • 6.4 ArrayList和LinkedList的区别
  • 7. Set 子接口
  • 8. Set 实现类
    • 8.1 HashSet 类
    • 8.2 TreeSet 类
  • 9. Collections 工具类
  • Java编程基础教程系列

1. 概念

集合是对象的容器,定义了多个对对象操作的方法,实现了和数组一样的功能,集合类全部位于java.util.* 包中,使用该类前需要进行导包操作导入相应的 Java 类。

先上脑图:

在这里插入图片描述

那么集合和前面学习的数组有什么区别呢?

2. 集合和数组的区别

集合和数组主要有两个方面的区别,首先是数组的长度是固定的,而集合长度不固定。其次是,数组可以存储基本数据类型和引用数据类型的变量,而集合只能存储引用数据类型的变量。

对于基本数据类型,我们一般进行装箱操作后即可存储在集合中,即把基本数据类型的变量封装成包装类的对象。这也体现了 Java 万物皆对象的特点。

3. 集合的体系结构

Java中封装了很多的集合类,接下类的一段时间,我们就要一起探讨 Java 集合类的学习。由于Java集合类的知识繁杂,所以我们要先了解 Java 集合的体系结构,然后进行深入的学习。

Java集合结构庞大,其主要分为两大类,单列集合 Collection 和双列集合 map。所谓的单列集合是一次只能添加一个数据,而双列集合就是一次可以添加一对数据。

接下来从这两大类开始学习,首先要学习的是单列集合 Collection 体系集合:

在这里插入图片描述

4. Collection父接口

Collection 接口位于整个集合体系的最顶层,是一个根接口。 JDK 不提供此接口的任何直接实现,它提供了更具体的子接口的实现,如 Set 和 List ,两个接口具有不同的功能。

Lsit 接口的特点是添加的元素有序,可重复,有索引。有序指的是存取顺序,可重复是指集合中允许重复元素的存在,有索引是指每个元素都有对应的索引。 Set 接口添加的元素的特点相反,无序,不可重复,无索引。

Interface Collection 表示一组任意类型的对象。 一些集合允许重复元素,而其他集合不允许。我们主要从添加元素删除元素遍历集合等方面学习 Collection 的使用。

常用的方法:

boolean add(Object obj) //添加一个对象。
boolean addAll(Collection c) //讲一个集合中的所有对象添加到此集合中。
void clear() //清空此集合中的所有对象。
boolean contains(Object o) //检查此集合中是否包含o对象。
boolean equals(Object o) //比较此集合是否与指定对象相等。
boolean isEmpty() //判断此集合是否为空。
boolean remove(Object o) //在此集合中移除o对象。
int size() //返回此集合中的元素个数。
Object[] toArray() //姜此集合转换成数组。

示例:创建集合,添加元素,删除元素,遍历集合元素

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class Test {public static void main(String[] args) {//创建集合Collection collection=new ArrayList();//添加元素collection.add("张三");collection.add("李四");//打印元素个数System.out.println("元素个数:"+collection.size());//打印集合System.out.println(collection);//删除元素collection.remove("张三");System.out.println("此时元素个数:"+collection.size());//遍历集合元素//1.增强forfor(Object object :collection){System.out.println(object);}//2.迭代器Iterator iterator=collection.iterator();while(iterator.hasNext()){String s=(String)iterator.next();System.out.println(s);}}
}

这里添加的是字符串类型的对象到集合中,我们还可以添加任何类型的对象到集合中。需要注意的是在使用迭代器遍历集合元素时,不可以使用该集合类的删除方法,会引发并发修改异常。此时,如果要删除元素,可以使用迭代器中的 remove() 方法。

在使用迭代器遍历集合元素时,首先使用 hasNext() 方法,判断集合中是否还有剩余元素,如果有,使用 next() 方法拿到该元素,同时还可以使用 remove() 方法删除该元素。

5. List 子接口

List 接口继承自 Collection 接口,其具有有序,可重复,有索引的特点。我们可以使用索引来对集合元素进行操作。除了 Collection 接口中的方法外,List 还另外的定义了很多方法来对集合元素进行操作。

示例:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;public class Test {public static void main(String[] args) {//创建集合List list = new ArrayList<>();//添加元素list.add("李四");list.add("王五");list.add("小张");list.add("小明");list.add("小王");list.add(0, "张三");//打印集合元素个数System.out.println(list.size());//打印集合元素System.out.println(list);//删除集合元素list.remove(2);System.out.println(list);//遍历集合元素for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}//使用列表迭代器遍历集合元素ListIterator lit = list.listIterator();while (lit.hasNext()) {System.out.println(lit.nextIndex() + ":" + lit.next());}while (lit.hasPrevious()) {System.out.println(lit.previousIndex() + ":" + lit.previous());}//判断System.out.println(list.contains("张三"));System.out.println(list.isEmpty());//获取元素位置System.out.println(list.indexOf("李四"));//获取其子集,左闭右开List list1 = list.subList(1, 3);System.out.println(list1);}
}

不同与 Collection 接口的是,我们可以利用索引删除集合元素,在遍历集合元素时,除了之前的方法,由于多了元素的索引,所以我们还可以使用 for 循环来遍历,同时还添加了列表迭代器来遍历集合元素。

6. List 实现类

6.1 ArrayList 类

ArrayList 实现类集合是使用数组实现的,其特点是查询快,增删慢。运行效率快,但是线程不安全。

ArrayList 实现了 List 接口,而 List 接口继承自 Collection 接口,所以它继承了两者的方法,。

示例:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;public class Test {public static void main(String[] args) {//创建集合ArrayList arrayList=new ArrayList();//添加元素Student s1=new Student("张三",18);Student s2=new Student("李四",19);Student s3=new Student("王五",20);arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);//打印集合System.out.println(arrayList.size());System.out.println(arrayList.toString());//删除元素arrayList.remove(s1);System.out.println(arrayList.size());System.out.println(arrayList.toString());//使用迭代器遍历ListIterator lt=arrayList.listIterator();while (lt.hasNext()){Student s=(Student) lt.next();System.out.println(s);}//判断System.out.println(arrayList.isEmpty());System.out.println(arrayList.contains(s1));//查找System.out.println(arrayList.indexOf(s2));}
}

这里我们使用了学生类举例:

/*
* 学生类
*/
public class Student {private String name;private int age;public Student(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;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age +"]";}
}

6.2 Vector 类

Vector 实现类集合也是采用数组实现的,其不同于 ArrayList 的是运行效率较慢,但是线程安全。

Vector 实现了 List 接口,而 List 接口继承自 Collection 接口,所以它继承了两者的方法, 因为在开发中这个类已经不在常用了,所以只对类本身新增的几个方法讲解一下。

示例:

import java.util.Vector;public class Test {public static void main(String[] args) {//创建集合Vector vector=new Vector();//添加元素vector.add("张三");vector.add("李四");vector.add("王五");//增加的方法System.out.println(vector.firstElement());System.out.println(vector.lastElement());System.out.println(vector.elementAt(2));}
}

6.3 LinkedList 类

LinkedList 实现类采用双向链表结构实现,增删快,查询慢。

在这里插入图片描述
同样的,LinkList 实现了 List 接口,而 List 接口继承自 Collection 接口,所以它继承了两者的方法, 其使用基本相似,这里不在赘述,需要强调的是,此类的集合也可以使用类似于前面的方法进行遍历。

在前面讲解的三种 List 的实现类集合中,由于集合中的元素是有索引存在的,所以在进行删除元素时,我们不仅可以利用索引删除元素,还可以利用引用删除元素。其底层是利用了 equals() 方法判断两个引用地址是否相同,这里可以重写 equals() 方法,用来判断对象的内容是否相同。

6.4 ArrayList和LinkedList的区别

在这里插入图片描述

我们已经探讨了两者的基本使用,前面说到,前者使用数组结构存储,而后者是双向链表的结构存储,所以,两者不同点在于,前者在内存中占用地址连续的内存空间,而后者的地址空间可能不连续。

7. Set 子接口

Set 接口位于 java.util 包中,Set 是一个无序集合,即存入和取出数据的顺序不一定相同。Set 集合中不可以添加重复元素。

Set 接口除了继承自 Collection 接口的所有方法如 add,equals 和 hashCode 方法外 , 还增加了其他规定。 下面使用往集合中添加学生类举例:

/*
* 学生类
*/
public class Student {private String name;private int age;public Student(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;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age +"]";}
}

List 是一个接口,所以不能实例化对象,这里创建 List 的引用指向其实现类 HashSet 的对象。

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class Test {public static void main(String[] args)  {/*set接口的使用:继承自Collection的接口,使用方法类似。特点是无序,不可重复,无索引*///创建集合Set<String> hashSet = new HashSet<String>();//添加数据hashSet.add("x");hashSet.add("z");hashSet.add("y");System.out.println(hashSet.size());System.out.println(hashSet);//删除数据hashSet.remove("x");System.out.println(hashSet.size());System.out.println(hashSet);//遍历数据for(String s:hashSet){System.out.println(s);}Iterator<String> iterator = hashSet.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}//判断System.out.println(hashSet.contains("y"));System.out.println(hashSet.isEmpty());}
}

Java 8 以后,new HashSet 中的 String 可以省略,并且集合中的数据具有无序性,如上述字符串打印时一般按字母顺序排列。

遍历集合中的数据时,由于 List 集合中的元素没有索引,索引无法使用 fori 的方法遍历,但是同样可以是使用增强 for 和迭代器的方法进行遍历。

8. Set 实现类

8.1 HashSet 类

HashSet 类位于 java.util 包中,其实现了 Set 接口。HashSet 类集合使用哈希表的方式存储数据,数据不可重复。

示例:

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;public class Test {public static void main(String[] args)  {/*HashSet使用:实现了Set接口,常用方法类似,使用哈希表(链接+数组+红黑树)的方式存储数据不可存储重复数据*///创建集合HashSet<Student> students = new HashSet<>();//添加数据Student s1 = new Student("zhang",18);Student s2 = new Student("li",19);Student s3 = new Student("wang", 20);students.add(s1);students.add(s2);students.add(s3);System.out.println(students.size());System.out.println(students.toString());//删除数据students.remove(s3);//遍历集合for (Student s:students) {System.out.println(s);}Iterator<Student> iterator = students.iterator();while(iterator.hasNext()){System.out.println( iterator.next());}//判断System.out.println(students.contains(s1));System.out.println(students.isEmpty());}
}

8.2 TreeSet 类

同样的,TreeSet 类也位于 java.util 包中,其实现了 Set 接口,使用方法十分类似。TreeSet 类集合使用了红黑数的方式存储数据,集合中数据不可重复。

该类实现了 SortSet 接口,对集合元素自动排序。并且元素对象的类型必须实现 Comparable 接口,指定排序规则,该接口中只有一个 CompareTo 方法,必须重写该方法来确定是否为重复元素,否则程序会出现异常。

在这里插入图片描述

示例:

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;public class Test {public static void main(String[] args)  {/*TreeSet使用:实现了Set接口,常用方法类似,使用红黑树的方式存储数据不可存储重复数据*///创建集合TreeSet<Student> students = new TreeSet<Student>();//添加数据Student s1 = new Student("zhang",18);Student s2 = new Student("li",19);Student s4 =new Student("zhang",18);students.add(s1);students.add(s2);students.add(s4);//删除数据students.remove(s1);//遍历集合for (Student s:students) {System.out.println(s);}//判断System.out.println(students.contains(s2));System.out.println(students.isEmpty());}
}

集合中的元素对象的类必须实现Comparable 接口,重写该接口中的CompareTo 方法。示例:

public class Student implements Comparable<Student>{@Overridepublic int compareTo(Student o) {int n1 = this.getName().compareTo(o.getName());int n2 = this.age - o.getAge();return n1 == 0 ? n2 : n1;
}

除了实现 Comparable 接口里的比较方法,TreeSet 也提供了一个带比较器 Comparator 的构造方法,使用匿名内部类来实现它。示例:

import java.util.Comparator;
import java.util.TreeSet;public class Test {public static void main(String[] args) {TreeSet<Student> persons=new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {// 先按年龄比较// 再按姓名比较int n1=o1.getAge()-o2.getAge();int n2=o1.getName().compareTo(o2.getName());return n1==0?n2:n1;}});Student s1=new Student("x",21);Student s2=new Student("z", 22);Student s3=new Student("y", 21);persons.add(s1);persons.add(s2);persons.add(s3);System.out.println(persons.toString());}
}

9. Collections 工具类

Collections 集合工具类不同于前面的 Collection 类,是两个完全不同的概念。Collections 类位于 java.util 包中。Collections 类提供了一系列的静态方法,可以实现对集合元素的排序,添加一些元素,随机排序,替换等操作。

一些常用的方法的示例:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class Test {public static void main(String[] args)  {/*Collections工具类*/List<Integer> integers = new ArrayList<Integer>();integers.add(11);integers.add(2);integers.add(13);integers.add(8);//排序Collections.sort(integers);System.out.println(integers.toString());//复制List<Integer> dest=new ArrayList<Integer>();for (int i = 0; i < 4; i++) {dest.add(0);}Collections.copy(dest,integers);System.out.println(dest.toString());//二分查找int i=Collections.binarySearch(integers,11);System.out.println(i);//反转Collections.reverse(integers);System.out.println(integers);//打乱Collections.shuffle(integers);System.out.println(integers);//把List转为数组Integer[] array= integers.toArray(new Integer[0]);System.out.println(array.length);System.out.println(Arrays.toString(array));//数组转为List;受限类型,此时不允许该集合中数据的增删操作。Integer[] arr={1,2,4,3,6};List<Integer> ints = Arrays.asList(arr);System.out.println(ints.toString());}
}

Collections 类不能 new 对象,不是因为没有构造方法,而是因为 Collections 的构造方法被私有化处理了。但是调用方法可以直接通过类名调用 Collections 类的方法,因为 Collections 类中的方法都是被 static修饰了,可以直接用类名调用。


Java编程基础教程系列

【Java基础】Java常用类详解

【Java基础】Java API文档使用详解

【Java基础】Java 包的使用详解


http://www.ppmy.cn/news/12619.html

相关文章

linux 中 PCIE 中断映射机制

PCIE 中断映射机制 1、 PCIE 中有三种中断方式&#xff0c; MSI&#xff0c;MSI-X 和INTx PCIe总线继承了PCI总线的所有中断特性&#xff08;包括INTx和MSI/MSI-X&#xff09;&#xff0c;以兼容早期的一些PCI应用层软件。 PCI总线最早采用的中断机制是INTx&#xff0c;这是…

Java图形化界面---JOptionPane

目录 一、JOptionPane的介绍 二、JOptionalPane的使用 &#xff08;1&#xff09;消息对话框 &#xff08;2&#xff09; 确认对话框 &#xff08;3&#xff09;输入对话框 &#xff08;4&#xff09;选项对话框 一、JOptionPane的介绍 通过JOptionPane可以非常方便地创建…

SpringBoot单元测试

目录 1、JUnit5 的变化 2、JUnit5常用注解 3、断言&#xff08;assertions&#xff09; 4、前置条件&#xff08;assumptions&#xff09; 5、嵌套测试 6、参数化测试 7、迁移指南 1、JUnit5 的变化 官网&#xff1a;JUnit 5 User Guide Spring Boot 2.2.0 版本开始引入 JUni…

图像处理解决流程--外观检测

一、图像外观检测和面积计算 1、获取标准图像&#xff0c;提取要测定的区域&#xff08;截取成多个ROI&#xff09; 2、将目标图像的位置进行平移和旋转&#xff08;将目标图像和标准图像进行重叠&#xff09; 3、根据标准图像的区域进行以此计算目标图像的信息 4、判断统计 二…

【MySQL】运算符及相关函数详解

序号系列文章3【MySQL】MySQL基本数据类型4【MySQL】MySQL表的七大约束5【MySQL】字符集与校对集详解6【MySQL】MySQL单表操作详解文章目录前言MySQL运算符1&#xff0c;算术运算符1.1&#xff0c;算术运算符的基本使用1.2&#xff0c;常用数学函数的基本使用2&#xff0c;比较…

译文 | Kubernetes 1.26:PodDisruptionBudget 守护不健康 Pod 时所用的驱逐策略

对于 Kubernetes 集群而言&#xff0c;想要确保日常干扰不影响应用的可用性&#xff0c;不是一个简单的任务。上月发布的 Kubernetes v1.26 增加了一个新的特性&#xff1a;允许针对 PodDisruptionBudget (PDB) 指定不健康 Pod 驱逐策略&#xff0c;这有助于在节点执行管理操作…

我的2022

我的2022高考结束的暑假前言高考结束编程的引路人学校生活差点放弃蓝桥杯报名寒假期间摆烂的假期卷王结束我的摆烂假期23年计划寄语&#x1f389;welcome&#x1f389; ✒️博主介绍&#xff1a;一名大一的智能制造专业学生&#xff0c;在学习C/C的路上会越走越远&#xff0c;后…

大数据技术架构(组件)——Hive:环境准备1

1.0.1、环境准备1.0.1.0、maven安装1.0.1.0.1、下载软件包1.0.1.0.2、配置环境变量1.0.1.0.3、调整maven仓库打开$MAVEN_HOME/conf/settings.xml文件&#xff0c;调整maven仓库地址以及镜像地址<settings xmIns"http://maven.apache.org/SETTINGS/1.0.0"xmIns:xsi…