您当前的位置: 首页 >  Java

liaowenxiong

暂无认证

  • 2浏览

    0关注

    1171博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Java集合类原理详解

liaowenxiong 发布时间:2021-02-19 21:38:55 ,浏览量:2

文章目录
  • 1 集合框架
    • 1.1 集合框架概述
      • 1.1.1 容器简介
      • 1.1.1 容器的分类
    • 1.2 Collection
      • 1.2.1 常用方法
      • 1.2.2 迭代器
    • 1.3 List
      • 1.3.1 概述
      • 1.3.2 常用方法
      • 1.3.3 实现原理
    • 1.4 Map
      • 1.4.1 概述
      • 1.4.2 常用方法
      • 1.4.3 Comparable 接口
      • 1.4.4 实现原理
      • 1.4.5 覆写 hashCode()
    • 1.5 Set
      • 1.5.1 概述
      • 1.5.2 常用方法
      • 1.5.3 实现原理
    • 1.6 总结:集合框架中常用类比较
  • 2 练习
  • 3 附录:排序

1 集合框架 1.1 集合框架概述 1.1.1 容器简介

到目前为止,我们已经学习了如何创建多个不同的对象,定义了这些对象以后,我们就可以利用它们来做一些有意义的事情。

举例来说,假设要存储许多雇员,不同的雇员的区别仅在于雇员的身份证号。我们可以通过身份证号来顺序存储每个雇员,但是在内存中实现呢?是不是要准备足够的内存来存储 1000个雇员,然后再将这些雇员逐一插入?如果已经插入了 500条记录,这时需要插入一 个身份证号较低的新雇员,该怎么办呢?是在内存中将 500 条记录全部下移后,再从开头插 入新的记录? 还是创建一个映射来记住每个对象的位置?当决定如何存储对象的集合时,必须考虑如下问题。

对于对象集合,必须执行的操作主要以下三种: ♦添加新的对象 ♦删除对象 ♦查找对象

我们必须确定如何将新的对象添加到集合中。可以将对象添加到集合的末尾、开头或者中间的某个逻辑位置。

从集合中删除一个对象后,对象集合中现有对象会有什么影响呢?可能必须将内存移来 移去,或者就在现有对象所驻留的内存位置下一个“洞”?

在内存中建立对象集合后,必须确定如何定位特定对象。可建立一种机制,利用该机制 可根据某些搜索条件(例如身份证号)直接定位到目标对象;否则,便需要遍历集合中的每 个对象,直到找到要查找的对象为止。

前面大家已经学习过了数组。数组的作用是可以存取一组数据。但是它却存在一些缺点, 使得无法使用它来比较方便快捷的完成上述应用场景的要求。

  1. 首先,在很多数情况下面,我们需要能够存储一组数据的容器,这一点虽然数组可 以实现,但是如果我们需要存储的数据的个数多少并不确定。比如说,我们需要在 容器里面存储某个应用系统的当前的所有的在线用户信息,而当前的在线用户信息是时刻都可能在变化的。 也就是说,我们需要一种存储数据的容器,它能够自动的改变这个容器的所能存放的数据数量的大小。这一点上,如果使用数组来存储的话,就显得十分的笨拙。

  2. 我们再假设这样一种场景:假定一个购物网站,经过一段时间的运行,我们已经存储了一系列的购物清单了,购物清单中有商品信息。如果我们想要知道这段时间里 面有多少种商品被销售出去了。那么我们就需要一个容器能够自动的过滤掉购物清 单中的关于商品的重复信息。如果使用数组,这也是很难实现的。

  3. 最后再想想,我们经常会遇到这种情况,我知道某个人的帐号名称,希望能够进一 步了解这个人的其他的一些信息。也就是说,我们在一个地方存放一些用户信息, 我们希望能够通过用户的帐号来查找到对应的该用户的其他的一些信息。再举个查字典例子:假设我们希望使用一个容器来存放单词以及对于这个单词的解释,而当 我们想要查找某个单词的意思的时候,能够根据提供的单词在这个容器中找到对应的单词的解释。如果使用数组来实现的话,就更加的困难了。

为解决这些问题,Java里面就设计了容器集合,不同的容器集合以不同的格式保存对象。

数学背景

在常见用法中,集合(collection)和数学上直观的集(set)的概念是相同的。集是 一个唯一项组,也就是说组中没有重复项。实际上, “集合框架”包含了一个 Set 接口和许 多具体的 Set 类。但正式的集概念却比 Java 技术提前了一个世纪,那时英国数学家 George Boole 按逻辑正式的定义了集的概念。大部分人在小学时通过我们熟悉的维恩图 引入的“集的交”和“集的并”学到过一些集的理论。

在这里插入图片描述

集的基本属性如下:

♦集内只包含每项的一个实例 ♦集可以是有限的,也可以是无限的 ♦可以定义抽象概念

集不仅是逻辑学、数学和计算机科学的基础,对于商业和系统的日常应用来说,它也很实用。 “连接池”这一概念就是数据库服务器的一个开放连接集。 Web 服务器必须管理客户机和连 接集。文件描述符提供了操作系统中另一个集的示例。

映射是一种特别的集。它是一种对(pair)集,每个对表示一个元素到另一元素的单向映射。 一些映射示例有: ♦ IP地址到域名(DNS)的映射 ♦ 关键字到数据库记录的映射 ♦ 字典(词到含义的映射) ♦ 2 进制到 10 进制转换的映射

就像集一样,映射背后的思想比 Java 编程语言早的多,甚至比计算机科学还早。而 Java 中的 Map 就是映射的一种表现形式。

1.1.1 容器的分类

既然您已经具备了一些集的理论,您应该能够更轻松的理解“集合框架”。 “集合框架” 由一组用来操作对象的接口组成。不同接口描述不同类型的组。在很大程度上,一旦您理解 了接口,您就理解了框架。虽然您总要创建接口特定的实现,但访问实际集合的方法应该限制在接口方法的使用上;因此,允许您更改基本的数据结构而不必改变其它代码。框架接口 层次结构如下图所示。

在这里插入图片描述

Java 容器类类库的用途是“保存对象”,并将其划分为两个不同的概念: 1) Collection 。 一组对立的元素,通常这些元素都服从某种规则。List必须保持元素特定 的顺序,而 Set 不能有重复元素。

2) Map 。 一组 成对的“键值对”对象。初看起来这似乎应该是一个 Collection ,其元素 是成对的对象,但是这样的设计实现起来太笨拙了,于是我们将Map明确的提取出来形 成一个独立的概念。另一方面,如果使用Collection表示Map的部分内容,会便于查看 此部分内容。因此Map 一样容易扩展成多维Map,无需增加新的概念,只要让Map 中的键值对的每个"值”也是一个Map即可。

Collection 和 Map 的区别在于容器中每个位置保存的元素个数。 Collection 每个位置只能保 存一个元素(对象)。此类容器包括:List,它以特定的顺序保存一组元素;Set则是元素 不能重复。

Map保存的是“键值对”,就像一个小型数据库。我们可以通过“键”找到该键对应的“值”。

♦ Collection -对象之间没有指定的顺序,允许重复元素。 ♦ Set - 对象之间没有指定的顺序,不允许重复元素 ♦ List- 对象之间有指定的顺序,允许重复元素,并引入位置下标。 ♦ Map - 接口用于保存关键字(Key)和数值(Value)的集合,集合中的每个对象 加入时都提供数值和关键字。 Map 接口既不继承 Set 也不继承 Collection。

List、Set、Map共同的实现基础是Object数组。

除了四个历史集合类外, Java2 框架还引入了六个集合实现,如下表所示。

在这里插入图片描述 这里没有 Collection 接口的实现,接下来我们再来看一下下面的这张关于集合框架的大 图:

在这里插入图片描述

这张图看起来有点吓人,熟悉之后就会发现其实只有三种容器:Map, List和Set,它 们各自有两个三个实现版本。

1.2 Collection 1.2.1 常用方法

Collection 接口用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时, 就使用这一接口。Collection在前面的大图也可以看出,它是List和Set的父类。并且它本 身也是一个接口。它定义了作为集合所应该拥有的一些方法。如下: 在这里插入图片描述 注意: 集合必须只有对象,集合中的元素不能是基本数据类型。

Collection 接口支持如添加和除去等基本操作。设法除去一个元素时,如果这个元素存在, 除去的仅仅是集合中此元素的一个实例。

♦ boolean add(Object element) ♦ boolean remove(Object element)

Collection 接口还支持查询操作:

♦ int size() ♦ boolean isEmpty() ♦ boolean contains(Object element) ♦ Iterator iterator()

组操作 :Collection 接口支持的其它操作,要么是作用于元素组的任务,要么是同时作用 于整个集合的任务。

♦ boolean containsAll(Collection collection) ♦ boolean addAll(Collection collection) ♦ void clear() ♦ void removeAll(Collection collection) ♦ void retainAll(Collection collection)

containsAll() 方法允许您查找当前集合是否包含了另一个集合的所有元素,即另一个 集合是否是当前集合的子集。其余方法是可选的,因为特定的集合可能不支持集合更改。 addAll() 方法确保另一个集合中的所有元素都被添加到当前的集合中,通常称为并。 clear() 方法从当前集合中除去所有元素。 removeAll() 方法类似于 clear() ,但 只除去了元素的一个子集。 retainAll() 方法类似于 removeAll() 方法,不过可能 感到它所做的与前面正好相反:它从当前集合中除去不属于另一个集合的元素,即交。

我们看一个简单的例子,来了解一下集合类的基本方法的使用:

import java.util.*;
public class CollectionToArray {
public static void main(String[] args)	{
Collection collection1 = new ArrayList();//仓U建一个集合对象
collection1.add("000"); //添加对象到Collection 集合中
collection1.add("111");
collection1.add("222");
System.out.println("集合collection1的大小:"+collection1.size ());
System.out.println("集合collection1的内容: "+collection1);
collection1.remove ("000") ;//从集合collection1中移除掉"000"这个 对象
System.out.println("集合collection1移除 000 后的内容:"+collection1);
System.out.println("集合collection1中是否包含000 :"+collection1.contains("000"));
System.out.println("集合collection中是否包含111:"+collection1.contains("111"));
Collection collection2 = new ArrayList();
collection2.addAll(collection1);//将collection1集合中的元素全部添加到collection2 中
System.out.println("集合collection2的内容:"+collection2);
collection2.clear();//清空集合 collection1 中的元素
System.out.println("集合collection2是否为空 :"+collection2.isEmpty());
//将集合collection1转化为数组
Object s[] = collection1.toArray();
for(int i=0;i            
关注
打赏
1661566967
查看更多评论
0.0506s