Java SE —— Set 接口

概述

  • 集合又称对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
  • 与数组的区别:
    • (1)数组长度固定,集合长度可变
    • (2)数组可以存储基本类型和引用类型,集合只能存储引用类型
  • 位置:java.util.*
    各集合继承关系如图:
    在这里插入图片描述
    JDK快速访问地址

Set 接口

java.util.set接口继承 Collection 接口

特点:不能存储重复元素;存取无序;没有索引(即不能使用普通的 for 循环遍历)

(一)HashSet

java.util.HashSet 集合实现 Set接口

特点:底层是哈希表结构(查询速度快),基于HashCode 实现元素不重复

存储过程:

  • ① 根据hashcode计算保存的位置,如果此位置为空,则直接保存,若不为空则执行 ② 。
  • ② 执行equals 方法,如果equals 方法为true,则认为是重复的,否则,形成链表。
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * @author Nigori
 * @date 2020/5/13
 **/
public class SetTest_01 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        set.add("aaa");
        set.add("ccc");
        set.add("ccc");
        set.add("ggg");
        
        //使用迭代器或者foreach遍历set集合
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

结果展示:
在这里插入图片描述
为什么不能存储重复的元素?
答:当存入元素的哈希码相同时,会调用equals() 进行确认,如果为true,则拒绝后者元素存入。

哈希值为一个逻辑地址。在Object 类中 int hashCode() 返回该对象的哈希码值。

public native int hashCode();   //native:代表该方法调用本地操作系统的方法

哈希表结构图解:
在这里插入图片描述
代码解释:
在这里插入图片描述
 
HashSet 存储自定义类型(重点)
重写 hashCode() and equals() 方法   ★★★
在这里插入图片描述
测试类 HashSetTest.java

import java.util.HashSet;
import java.util.Set;

/**
 * @author Nigori
 * @date 2020/5/13
 **/
public class HashSetTest {

    public static void main(String[] args) {
        addHashTest();
    }
    public static void addHashTest() {
        Set<Person> setPerson = new HashSet<>();
        Person person_1 = new Person("小明",20);
        Person person_2 = new Person("小明",20);
        Person person_3 = new Person("小明",21);

        System.out.println(person_1.hashCode());   //1908153060  //23458774
        System.out.println(person_2.hashCode());   //116211441   //3458774
        System.out.println(person_3.hashCode());   //607635164   //23458775

        System.out.println(person_1 == person_2);   //false   //false
        System.out.println(person_1.equals(person_2));   //false   //true

        setPerson.add(person_1);
        setPerson.add(person_2);
        setPerson.add(person_3);

        System.out.println(setPerson);
        //[Person{name='小明', age=20}, Person{name='小明', age=21}, Person{name='小明', age=20}]
        //[Person{name='小明', age=21}, Person{name='小明', age=20}]     重写 hashCode() and equals()

        //setPerson.remove(person_1);
        setPerson.remove(new Person("小明",21));      //必须重写hashCode() 和 equals()
        System.out.println(setPerson);      //[Person{name='小明', age=20}]
    }
}

自定义类型 Person.java

import java.util.Objects;

/**
 * @author Nigori
 * @date 2020/5/13
 **/
public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Objects.equals(name, person.name);
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
(二)LinkedHashSet

java.util.LinkedHashSet 继承自 HashSet

特点:底层是一个哈希表(数组+链表/红黑树) + 链表的结构,后者链表用来记录元素的存储顺序,保证元素有序 。但不允许有重复元素。

(三)TreeSet

特点:红黑树的存储结构,基于排列顺序实现元素不重复;实现了SortedSet接口,对集合元素自动排序。
这里主要介绍:自定义类型

		//Person 没有实现 Comparable 接口,报 ClassCastException 异常
		TreeSet<Person> treeSet = new TreeSet<>();
        Person person_1 = new Person("zds",20);
        Person person_2 = new Person("thf",22);
        Person person_3 = new Person("asg",21);

        treeSet.add(person_1);
        treeSet.add(person_2);
        treeSet.add(person_3);
        System.out.println(treeSet.size());

方式一:通过实现 Comparable< T > 接口,重写 compareTo() 方法,返回值为 0,认为重复
Person类中有:

public class Person implements Comparable<Person> {

    private String name;
    private int age;

	/* 省略了构造方法和getter,setter方法 */
    
    @Override
    public int compareTo(Person o) {
        int numb1 = this.getName().compareTo(o.getName());
        int numb2 = this.getAge() - o.getAge();
        return numb1 == 0 ? numb2 : numb1;
    }
}
		TreeSet<Person> treeSet = new TreeSet<>();
		Person person_1 = new Person("zds",20);
        Person person_2 = new Person("thf",22);
        Person person_3 = new Person("asg",21);

        treeSet.add(person_1);
        treeSet.add(person_2);
        treeSet.add(person_3);
        System.out.println(treeSet.size());		// 3
        System.out.println(treeSet);	//[Person{name='asg', age=21}, Person{name='thf', age=22}, Person{name='zds', age=20}]

方式二:通过实现 Comparator< T > 接口,重写 compare(T o1, T o2); 方法

		TreeSet<Person> treeSet = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int num1 = o1.getAge() - o2.getAge();
                int num2 = o1.getName().compareTo(o2.getName());
                return num1 == 0 ? num2 : num1;
            }
        });
        Person person_1 = new Person("zds",20);
        Person person_2 = new Person("thf",22);
        Person person_3 = new Person("asg",21);

        treeSet.add(person_1);
        treeSet.add(person_2);
        treeSet.add(person_3);
        System.out.println(treeSet.size());		// 3
        System.out.println(treeSet);  //[Person{name='zds', age=20}, Person{name='asg', age=21}, Person{name='thf', age=22}]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Set 接口Java 中的一个接口,它继承了 Collection 接口,是一种不允许重复元素的集合。它有许多实现类,例如 HashSet 和 TreeSet,可用于存储一组无序的、不重复的元素。 ### 回答2: Java中的Set接口是一种集合,它是java.util包中的一部分。它是在Collection接口的基础上定义的,用于存储不重复的元素。Set接口不保证元素的顺序,也不允许存储重复的元素。 Set接口的特性可以总结如下: 1. 不允许存储重复的元素:Set接口中的实现类会根据元素的值来判断是否重复,如果重复则不会被添加到Set中。 2. 不保证元素的顺序:HashSetSet接口最常用的实现类,它使用哈希表数据结构来存储元素,不会按照插入顺序进行排序。而LinkedHashSet则会按照插入顺序进行排序。 3. 可以包含null元素:Set接口可以包含null元素,但是只能包含一个null元素,如果尝试添加多个null元素,只会保留一个。 Set接口提供了一系列常用的方法,如添加元素、删除元素、判断是否包含某个元素、获取元素个数等。一般情况下,我们使用Set接口来存储一组不重复的元素,以方便快速查找、去除重复元素等操作。 总之,Set接口Java中是用来存储不重复元素的集合。它具有不保证元素顺序和不允许存储重复元素的特性。我们可以使用Set接口来进行快速查找和去除重复元素的操作。 ### 回答3: 在Java中,Set接口是一种集合接口,它是java.util包中的一部分。Set接口继承自Collection接口,并且是一种不允许包含重复元素的集合。它是基于数学中的集合概念而设计的。 Set接口的特点是: 1. 不允许重复元素:Set中不允许包含重复的元素,如果试图将重复的元素添加到Set中,则添加操作会被忽略。 2. 无序性:Set中的元素没有特定的顺序,即不保证元素的存储顺序和插入顺序相同。 3. 无索引:Set接口不提供索引访问元素的方法,因为元素没有固定的位置。 4. 提供了高效的查找和判断功能:Set接口提供了contains()方法用于判断是否包含某个元素,以及size()方法获取Set中元素的个数。 Java中的Set接口有几个常用的实现类,例如HashSet、LinkedHashSet和TreeSet。 - HashSet是基于哈希表实现的Set接口,它提供了最快的查找速度,元素的顺序是不确定的。 - LinkedHashSet继承自HashSet,内部通过链表维护元素的插入顺序,所以可以按照插入顺序遍历元素。 - TreeSet是基于红黑树实现的Set接口,它可以保证元素有序。按照元素的自然顺序或者通过Comparator来进行排序。 Set接口在实际编程中经常用于去重、查找元素以及判断元素的存在与否等场景。它提供了一种快速、高效且简洁的方式来处理元素集合。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值