Java--集合(一)

简介: Hash函数?上面我们已经简单提到了,Hash表的内部是按照某种规则进行分类排列,那么接下来我们说一下常见的几种函数: 1.直接定法址; 2.数字分析法; 3.平方取中法; 4.折叠法; 5.取模(求余数);----这种最常用,集合内部散列就是这样实现的; 6.随机数法; 基本上就是这几种,应该都比较简单,大家一看就明白;关键在于2点,计算简单和分布均匀;

一、前序


   前几篇文章我结合数据结构说了一些常用的集合,但是我感觉那样可能不系统,于是乎想着重写,按照由整体到细节的方式去写,这样才能更好的把握集合,废话不多说开始吧;


二、集合框架

   

 1005447-20171107223408544-950719814.png

  上面这副图是集合框架中的基本接口,另外还有NavigableSet和NavigableMap这两个接口;看到这些接口如果你有些什么想法的话,那么恭喜你,你对Java集合掌握非常可以;这里述说下每个接口的主要作用以及常用的一些方法,等等针对于单个接口的实现的时候我们到时候具体再说也可以;

   1.Iterator接口:主要实现对集合进行迭代的迭代器;

   2.基本接口:Collection和Map,这2个接口里面封装基本的集合操作,比如add,put,get等一系列方法,总体比较简单;

   3.List接口:有序集合,这里面主要包括2种数据结构前面讲的很清楚了,另外还有获取元素的方法,迭代器,索引和随机访问,也就是上面的RandomAccess接口;

   4.ListIterator接口:这个是Iterator接口的子接口,这个定义一个可以在迭代器以前增加元素的方法;

   5.Set接口:Set接口等同于Collection接口,Set里面add里面不允许增加相同的元素;

   Java里面有个 很明显的特点,就是不直接继承接口,增加一层抽象类,然后在去实现抽象类,这样有个好处就是方便我们对抽象类扩展,一但继承接口那么就必须对接口下面的所有方法进行实现,但是抽象类却不需要;

 1005447-20171108083253669-1375261841.png

 1005447-20171108083318106-33475355.png

 以上简单对接口的整体框架进行介绍,接下来我们开始对每一个具体的实现进行详细介绍;


三、List接口


  实现这个接口的集合主要有ArryList,Vector和LinkedList,前面介绍数据接口的链表的时候已经介绍过,这里进行下对比;ArryList和Vector这两个集合就要是基于动态数组实现的,区别就在Vector是线程同步的,每一个方法都是synchronized修饰,这个地方的好处就在于读取的时候可以开2个线程同时访问这个集合,建议是不同步的时候使用ArryList,同步的时候使用Vector,LinkedList主要是基于双向链表实现,只要明白了数据结构相信这块的东西很简单,要是不明白的话可以看下我写的链表那2章;这里需要提一下LinkedList的迭代,LinkedList实现了ListIterator这个接口,可以用来遍历集合;


四、Set接口


   在明白这个之前我们先要了解一种数据结构--散列表(哈希表):

   什么是Hash?是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

   为什么需要Hash?上面已经简单提到出现Hash的目的,是为了快速查找到我们想要的数据,这个是针对于数组和链表结构的集合来说的,当我们需要查询集合中是否于某个元素相同的时候我们需要便利整个集合,然而我们使用Hash可以减少我们的次数;这个我们举个例子,好比我们在图书管找我们需要的一本书,假设图书管理员没有进行分类整理的话,那么我们需要在一堆乱七八糟的书堆里查找我们需要的书,但是图书管理进行分类以后我们只需要按照规则去我们需要的地方找我们需要的图书就好,那么在时间上我们就更加快速;

  Hash函数?上面我们已经简单提到了,Hash表的内部是按照某种规则进行分类排列,那么接下来我们说一下常见的几种函数:

  1.直接定法址;

  2.数字分析法;

  3.平方取中法;

  4.折叠法;

  5.取模(求余数);----这种最常用,集合内部散列就是这样实现的;

  6.随机数法;

  基本上就是这几种,应该都比较简单,大家一看就明白;关键在于2点,计算简单和分布均匀;

  Hash冲突?上面简单的说了一下Hash函数,我们考虑一下这个问题,就按照取模方法来说,肯定会有2个数字计算出的的余数相同,那么针对这种情况我们怎么办,怎么处理?这就是我们所说的冲突,接下来我们说一下处理冲突的手段:


  1.开放定址法,这个是基于数组实现的,根据不同的处理方式我们可以分为线性探测法,二次探测法,随机探测法,再散列函数法;这里做一下概述:当发生冲突的时候我们需要存放冲突的数据,线性探测法和二次线性探测法这两个方法主要是在自身的散列上存储数据,线性探测的就是在冲突的位置继续向下查找,直到找到为空的将数据存放,这一过程中难免会遇到已经有数据的位置,这种情况叫做聚集,影响效率,二次探测法就是将向寻址的结果平方,这样就可以向前向后查找,另外二次探测法可以避免聚集,基本上只是散列表为填满的时候,我们都可以使用上面2种方法解决冲突的问题;接下来就是在散列函数法,就是冲突的时候在增加一个散列表,重新计算地址然后将数据放入;

  2.链地址法,这个居于链表和数组的实现,就是当出现冲突的时候继续增加链表的节点,HashMap就是使用的这个方法;

  明白Hash是什么东西接下来我们开始看下Set接口下面的集合源码,篇幅估计会比较大,我们在下一节说;

相关文章
|
2月前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
53 6
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
48 3
|
2月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
38 2
|
15天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
36 5
|
27天前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
39 4
|
1月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
33 2
|
1月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
1月前
|
Java 开发者