java-set系列集合

152 阅读3分钟

屏幕截图 2023-11-30 175903.png

Set系列集合是无序,不重复,无索引的

Set接口中的方法上基本与collection的API一致

HashSet

HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。

HashSet 允许有 null 值。

HashSet 是无序的,即不会记录插入的顺序。

HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。

HashSet 实现了 Set 接口。

image.png 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差不多的

屏幕截图 2023-11-29 093122.png

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;
}

这样就可以实现了