Collection单列集合 ——Set接口

java.util.Set 接口和java.util.List 接口一样,同样继承自Collection 接口,

它与Collection 接口中的方法基本一致,并没有对Collection 接口进行功能上的扩充。

与List 接口不同的是, Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。


Set 接口常用子类:

HashSet集合

LinkedHashSet集合


Set 集合的特点:元素存取无序,无索引,不可重复

HashSet集合:

 HashSet<String> hs = new HashSet<>();
hs.add("abc");
hs.add("bca");
hs.add("cba");
System.out.println(hs);                 //输出:[bca, abc, cba]

可从以上代码看出,HashSet集合元素存取无序

HashSet集合底层是数组与链表加红黑树实现

Set集合存取无序原理:

当元素存入集合中时,便会自动创建一个16位的数组结构

然后根据存入元素的hashCode值%16判断元素存放在数组的哪一个位置

若欲存放的数组位置已有元素,则会判断该元素与已有元素的地址值是否相同

若地址值不同,则会通过equals()方法判断元素内容是否相同

若以上判断条件都不相同,则会在该数组位置上延伸一条链表结构,用来存放hashCode%16值相同,可是内容不同的元素

Set集合存放自定义对象:

创建一个自定义类将存放在Set集合上时,集合也会默认计算元素hashCode值

哈希值就是一个十进制的整数,每一个对象都有对应的哈希值

而自定义对象没有重写hashCode()方法前就是继承Object类的hashCode()方法  (也就是计算对象的地址值)

自定义对象没有重写equals()方法前也是继承Object类的equals()方法 (还是计算对象的地址值)

则我们要重写自定义对象的hashCode(),equals()方法

一般开发工具都能使用generate自动生成:

private String name;
private int age;
private double price;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Double.compare(student.price, price) == 0 &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, price);
    }

重写了euquals()方法和hashCode()方法后,就可以真正根据自定义对象的成员变量是否相同判断是否存入Set集合

HashSet<Student> hs = new HashSet();
Student s1 = new Student("1号同学", 22, 33.22);
Student s2 = new Student("1号同学", 22, 33.22);
Student s3 = new Student("2号同学", 23, 42.52);
Student s4 = new Student("3号同学", 20, 74.32);
Collections.addAll(hs, s1, s2, s3, s4);
System.out.println(hs);
//输出:
//[Student{name='2号同学', age=23, price=42.52}, 
//Student{name='3号同学', age=20, price=74.32},
//Student{name='1号同学', age=22, price=33.22}]

上图存入两个相同的s1,s2对象,可是集合中只会保存一个

增强for遍历Set集合:

Set集合没有索引没有存取顺序,则只能使用增强for和Iterator作遍历

具体使用方法见https://blog.csdn.net/weixin_42022555/article/details/81481889

HashSet<String> hs = new HashSet<>();
Collections.addAll(hs, "abcd", "bcad", "cbda", "dabc");
for (String str : hs) {
    String s = str;
    System.out.println(s);            //输出:dabc    cbda    bcad    abcd
}

Iterator迭代器遍历Set集合:

具体使用方法见https://blog.csdn.net/weixin_42022555/article/details/81481889

HashSet<String> hs = new HashSet<>();
Collections.addAll(hs, "abcd", "bcad", "cbda", "dabc");
Iterator<String> it = hs.iterator();
while (it.hasNext()) {
    String str = it.next();
    System.out.println(str);                //输出:dabc    cbda    bcad    abcd
}

猜你喜欢

转载自blog.csdn.net/weixin_42022555/article/details/81501513