set 接口

set 接口
特点:无序,不允许重复,是Collection接口的子接口
所有的方法都是Collection接口中所定义的方法

实现类
HashSet存储采用哈希表的方式进行存储,HashSet采用HashCode算法来存取集合中的元素,因此具有比较好的读取和查找性能
LinkedHashSet是在HashSet的基础上添加一个额外的链表结构可以记录存储数据的顺序
TreeSet采用的是树状结构进行数据存储

HashSet
类定义
public class Hshset
extends AbstractSet
implements Set ,Cloneable, java.io.Serializable
数据的存储方式
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
底层实现方法:存储到Set中的所有数据最终都存户在一个HashMap中,其中存储的数据采用key的方式进行存储,值为PRESENT常量
常用算法
1.boolean add(E e)向集合Set中添加元素,注意不保证顺序
2.设置hashCode和equals方法的调用
比对两个对象相等,调用流程为:1,调用对象的hashcode方法,如果hashCode不相等则返回,认为两个对象不相等。2.如果hash值相等则调用equals判断
潜规则要求:定义类时需要定义对应的hashCode和equals方法,要求:当equals为true时,hash值必须相等;当hash值相等时不一定equals为true
3,boolean remove(Object o) 删除指定对象,同样需要hashCode和equals方法
4.void clear() 清空集合中的所有元素
5.boolean contains(Object o) 判断集合中是否有指定的对象,同样需要hashCode和equals方法
6.int size() 获取集合中的元素个数
7.Iterator iterator()用于遍历所存储的数据

Set<String> set = new LinkedHashset<>();
	set.add("abc");
	set.add("123");
	Iterator<String> it = set.iterator();
	while(it.hasNext()){
		String temp = it.next();
		System.out.println(temp);
		}

HashSet 的特征
无序:不仅不能保护元素插入的顺序(如果需要顺序则可以使用 LinkedHashSet),而且在元素在以后的顺序也可能变化(这是由 HashSet 按 HashCode 存储对象(元素) 决定的,对象变化则可能导致 HashCode 变化)

如果需要访问的顺序和插入的顺序一致,可以使用HashSet的子类LinkedHashSet不允许重复[equals 和hashcode]

结论:
1、当HashSet判定对象重复时,首先调用的是对象的hashCode方法,如果两个对象的hashCode值相同时,才调用equals进行判定。如果hashCode值不相等则不会调用equals判断。如果hashcode相等二千equals为true,则后盖前。
2、HashSet是线程非安全的,方法上没有同步约束
3、HashSet元素可以为Null

LinkedHashSet
类定义

public class LinkedHashSet<E> 
		extends  HashSet<E>
		implements Set<E> ,Cloneable,java.io.Serializable{
		

没有什么新方法,仅仅是在HashSet的基础上添加了一个链表结构记录存取的顺序

LinkedHashSet 是HashSet的一个子类,LinkedHashSet也根据HashCode的值来决定元素的存储位置,但同时它还用一个链表来维护元素的插入顺程序,插入的时候既要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素

TreeSet
TreeSet实现了SortedSet 接口,顾名思义这是一种排序的Set集合

public class  TreeSet<E>  extends AbstractSet<E>
	implements NavagableSet<E> ,cloneable,java.io.Serializable

数据存储采用的是
private transient NavagableMap <E,Object> m;
private static final Object PRESENT = new Object();
在map中以key为需要存放的数据,以PERSENT常量为值存放数据

内部实现
底层是用TreeMap实现的,本质上是一个红黑树原理。正因为它是排序了的,所以相对HashSet来说,TreeSet提供了一些额外的按排序位置访问元素的方法,例如 first(),last(),lower(),higher(),subSet(),headSet(),tailSet()

TreeSet的排序分为两种类型,一种是自然排序,另一种是定制排序。
注意,要求添加到TreeSet中的元素类型必须实现Comparable接口

如果使用TreeSet时不会依靠hashcode和equals进行比较,相等性判断是依靠compareTo实现的

自然排序 (在元素中写排序规则)
TreeSet 会调用compareTo 方法比较元素大小,然后按 升序排序(从小到大),所以自然排序中的元素对象,都必须实现了Comparable接口,否则会抛出异常。对于TreeSet判断元素是否重复的标准,也是调用元素从Comparable 接口继承而来的compareTo方法,如果返回0则是重复元素。java的常见类都已经实现了Comparable接口,

哈希表
Hash一般翻译为“散列” ,也有直接音译为“哈希”的,这就是把任意长度的输入通过散列算法,变换成固定长度的输出,该输出就是散列值(哈希值);这种转换时一种压缩映射,散列值得空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,所以不可能从散列值来唯一的确定输入值
简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

所有散列函数都有如下一个基本特性:根据同一散列函数计算出的散列值如果不同,那么输入值肯定也不同。但是,根据同一散列函数计算出的散列值如果相同,输入值也不一定相同。

在java中任意一个对象都有一个hashCode()方法,可以获取任意一个对象的hash值。
public native int hashCode();

哈希冲突
当两个不同的输入值,根据同一散列函数计算出相同的散列值的现象,就把它叫做碰撞。(哈希碰撞)

散列算法
散列法 Hashing是一种将字符组成的字符串转换为固定长度(一般是更短长度)
的数值或索引值得方法,称为散列法,也叫哈希法

二叉树
二叉搜索树 (Binary Search Tree ,简称BST),BST是一种很常用的二叉树。
定义是:一个二叉树中,任意节点的值要大于等于左子树所有节点的值且小于等于右边子树的所有节点的值。
主要针对链表的插入和删除很快,但是查找数据却很慢的特点。树状结构最大的优势在于查找,但是插入和删除的效率都不太高
二叉树的特点:
左子树上所有结点的值均小于或等于它的根结点的值
右子树上所有结点的值均大于或等于它的根结点的值
左、右子树也分别为二叉排序树

前序遍历:根节点——》左子树——》右子树
中序遍历:左子树——》根节点——》右子树
后序遍历:左子树——》右子树——》根节点
在这里插入图片描述
中序遍历 1 2 3 4 5 6 7
前序遍历 5 2 1 4 3 6 7
后序遍历 1 3 4 2 7 6 5

二叉树在极端情况下会退化为链表结构,为了避免出现这个问题,引入平衡树
AVL 树是一种平衡二叉树,平衡二叉树递归定义如下:
左右子树的高度差小于等于1。
其每一个子树均为平衡二叉树。
AVL树引入了所谓监督机制,就是在树的某一部分的不平衡度超过一个阈值后触发相应的平衡操作。保证树的平衡度在可以接受的范围内。

引入红黑树。
红黑树是一种近似平衡的二叉查找树,查找、删除、插入都快,树经常需要进行旋转达到平衡,但是平衡算法很复杂。

红黑树特征:

1、每个节点不是红色就是黑色的;
2、根节点总是黑色的;
3、如果节点是红色的,则它的子节点必须是黑色的(反之不一定),(也就是从每个叶子到根的所有路径上不能有两个连续的红色节点);
4、从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值