Set系列集合是无序,不重复,无索引的
Set接口中的方法上基本与collection的API一致
HashSet
HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。
HashSet 允许有 null 值。
HashSet 是无序的,即不会记录插入的顺序。
HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。
HashSet 实现了 Set 接口。
HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。
HashSet底层原理
1.HashSet集合底层采用哈希表存储数据
2.哈希表是一种对于增删改查性能都较好的结构
哈希表的组成:数组+链表+红黑树
哈希值:
1.根据Hashcode方法(定义在object类中,默认使用地址值)算出的int类型整数
2.一般会重写HashSet方法,利用内部的属性值计算哈希值
@Override
public int hashCode() {
return Objects.hash(name, age);
}
这也也不需要自己写在ideal中按alt+enter选中hashcode 就也可以了
hashset也是不能添加重复的元素,在添加过程会调用equals方法判断元素的是否已经存在.
HashSet是根据元素的哈希值跟数组的长度计算出应存入的位置
LinkedHsetSet
有序,不重复,无索引.有序是指保证存入和取出的顺序一样
底层也是哈希表结构,之色每个元素有额外的多一个双链表机制记录存储的顺序
public static void main(String[] args) {
LinkedHashSet<String> lk=new LinkedHashSet<>();
lk.add("zhang");
lk.add("li");
lk.add("wang");
System.out.println(lk);
}
其中的方法也是和HashSet差不多的
TreeSet
不重复,无索引,可排序
可排序:按照元素的默认规则排序
集合底层是基于红黑树的数据结构实现排序的
对于整形数据默认是按照由小到大排序
TreeSet<Integer> ts = new TreeSet<>();
ts.add(3);
ts.add(6);
ts.add(4);
ts.add(8);
sout(ts)
输出为{3,4,6,8}
而字符串默认是按照首字母大ASCLL码表来进行比较的,首字母相同在比较后一个字母,也是按照从小到大的;
遍历方式:
迭代器
Iterator it = ts.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
增强for
for (Object t : ts) {
System.out.println(t);
}
lambda表达式:
ts.forEach(i-> System.out.println(i));
排序: 方式一: 比较是靠compareble接口来实现的,
public int compareTo(student o) {
return this.getAge()-o.getAge();
返回值:
负数:认定要添加元素是小的,存左边
正数:认定要添加元素是大的,存右边
0:认定要添加元素已经存在,舍弃
}
this 表示当前要添加的元素
o 表示已经在红黑树的元素
方式二:创建TreeSet对象时候,传递比较器comparator指定规则
TreeSet<String> ts=new TreeSet<>((o1, o2) ->o1.length()-o2.length());
用lambda方式来简化重写的comparator函数式接口
这样的话就是比较字符串的长度了
比较一个类中的数据是也可以在类中重写comparable接口的comparaTo方法
例: 就如比较学生的总分,相同的话比较数学成绩,还相同的话比较语文,再英语,年龄,名字
@Override
public int compareTo(student1 o) {
int sum1=this.getMath()+this.getEnglish()+this.getYuwen();
int sum2=o.getEnglish()+o.getYuwen()+o.getMath();
int i=sum1-sum2;
i=i==0?this.getMath()- o.getMath():i;
i=i==0?this.getYuwen()-o.getYuwen():i;
i=i==0?this.getEnglish()-o.getEnglish():i;
i=i==0?this.getAge()-o.getAge():i;
i=i==0?this.getName().compareTo(o.getName()):i;
return i;
}
这样就可以实现了