ArrayList的contains()方法会调用到indexOfRange()方法来判断集合内是否已经存在指定元素
而indexOfRange()方法则会在判断传入参数不为空的情况下遍历集合中的所有元素,
并调用传入参数的equals()来一个个的判断是否重复;
size:集合中的元素数量
o:传入参数public boolean contains(Object o) { return indexOf(o) >= 0; } public int indexOf(Object o) { return indexOfRange(o, 0, size); } int indexOfRange(Object o, int start, int end) { Object[] es = elementData; if (o == null) {//如果传入的参数为null for (int i = start; i < end; i++) { if (es[i] == null) { return i; } } } else {//如果传入参数不为null for (int i = start; i < end; i++) {//遍历集合中的元素以判断是否有重复 if (o.equals(es[i])) {//调用传入参数的equals()方法判断是否重复 return i;//如果重复则返回元素下标 } } } return -1; }
HashSet:
一.HashSet的无序
HashSet的无序指的是读取的顺序和加入的顺序不一致,且读取的顺序不可控制
造成这一原因是因为Hash会在加入数据时自动对集合内的数据进行依has值排序
二.HashSet的值不重复
HashSet会在加入数据时会判断加入的数据的has值是否已存在
若已存在,则调用加入数据的equals()方法来判断集合内是否已存在此数据
若不存在,则直接将其加入集合
注①:HashSet的底层为map集合
注②:HashSet获取has值的方法为调用元素的hashCode()方法
注③:HashSet基于哈希表(散列表)
TreeSet:
一. TreeSet的有序
TreeSet的有序并不是指读取的顺序与加入的顺序相同,而时其读取的顺序时可控的
与HashSet相同,TreeSet会在加入数据时会对集合内的数据进行排序
二.TreeSet的排序
TreeSet的排序分两种
1.自然排序
自然排序是在存储的对象自身有排序功能时,调用其compareTo()方法进行排序
若对象自身并没有排序功能,
可以让对象实现Comparable并重写其compareTo()方法来对对象进行排序;
如果对象自身没有排序功能,即未实现Comparable接口或未重写其compareTo方法
就会抛出转换异常;
2.选择器排序
选择器排序是专门撰写一个服务类,实现Comparator<T>()接口并重写compare方法
T为要排序的对象类型
排序的逻辑写在compare()方法中即可,
TreeSet在对对象排序是会自动调用其compare()方法
注①:TreeSet基于二叉树
注②:选择器的优先级比自然排序要高
注③:String的compareTo()方法就是遍历组成String对象的char,并一个一个的比较大小
注④:自然排序抛出转换异常的原因是试图将存储对象转换位Comparable()类,
也许部分类不会报错?
三.二叉树
二叉树可以理解为一个倒置的树状图
每个节点中都有一个值,
每个节点至多可以有两个分支,比父节点大的值在右边,小于父节点的值在左边
二叉树的子节点只能存在比父节点大或小的值
二叉树的读取顺序为从左至右,即从小到大
参考图