前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Java】11 Set 集合

【Java】11 Set 集合

作者头像
Demo_Null
发布2020-09-28 11:05:10
6680
发布2020-09-28 11:05:10
举报
文章被收录于专栏:Java 学习Java 学习

java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不同的是,Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

1.1 Set 接口

   Set 接口继承了 Collection 接口,因此可以使用 Collection 接口中的所有方法。由于 Set 集合中的元素不能重复,因此在向 Set 集合中添加元素时,需要先判断新增元素是否已经存在于集合中,再确定是否执行添加操作。

在这里插入图片描述
在这里插入图片描述

1.2 HashSet 集合

   HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时就是使用这个实现类。HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存取和查找性能。    当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode( ) 方法来得到该对象的 hashCode 值,然后根据该 hashCode 值决定该对象在 HashSet 中的存储位置。如果有两个元素通过 equals( ) 方法比较返回 true,但它们的 hashCode( ) 方法返回值不相等,HashSet 将会把它们存储在不同的位置,依然可以添加成功。也就是说,HashSet 集合判断两个元素相等的标准是两个对象通过 equals( ) 方法比较相等,并且两个对象的 hashCode( ) 方法返回值也相等。

1.2.1 HashSet 的特点

   ♝ 集合元素值可以是 null。    ♝ 不能保证元素的排列顺序,顺序可能与添加顺序不同。    ♝ HashSet 不是同步的,如果多个线程同时访问一个 HashSet,假设有两个或者两个以上线程同时修改了 HashSet 集合时,则必须通过代码来保证其同步。

1.2.2 示例

set 集合存放 字符串

代码语言:javascript
复制
public class Test {

    public static void main(String[] args) {
        HashSet<String> set = new HashSet<String>();
        set.add("刘备");
        set.add("关羽");
        set.add("张飞");
        set.add("刘备");

        System.out.println(set);
    }
}
在这里插入图片描述
在这里插入图片描述

set 存放 对象

代码语言:javascript
复制
// 学生类
public class Stu {
    private String name;
    private Integer age;

    public Stu(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "Stu{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


----------------------------------------------------------------------

// 测试类
public class Test {
    public static void main(String[] args) {
        HashSet<Stu> set = new HashSet<>();
        set.add(new Stu("刘备", 1000));
        set.add(new Stu("刘备", 1000));

        System.out.println(set);
    }
}
在这里插入图片描述
在这里插入图片描述

   为什么同的对象都会存到 set 集合,我们在 Stu 类中没有重写 equals、hashcode 方法,用的都是 Object 中的方法,当使用 Object 中的 equals 方法时,比较的是地址值,被认为不是一样的,这将导致 HashSet 会把这两个对象保存在 Hash 表的不同位置,从而使两个对象都可以添加成功。

set 存放 对象,重写 equals、hashcode

代码语言:javascript
复制
// 学生类
public class Stu {
    private String name;
    private Integer age;

    public Stu(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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

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

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


----------------------------------------------------------------------

// 测试类
public class Test {
    public static void main(String[] args) {
        HashSet<Stu> set = new HashSet<>();
        set.add(new Stu("刘备", 1000));
        set.add(new Stu("刘备", 1000));

        System.out.println(set);
    }
}
在这里插入图片描述
在这里插入图片描述

1.2.2 注意事项

   如果需要把某个类的对象保存到 HashSet 集合中,必须重写这个类的 equals( ) 方法和 hashCode( ) 方法时,如果两个对象通过 equals( ) 方法比较返回 true,这两个对象的 hashCode 值也应该相同。

1.3 LinkedHashSet 集合

   HashSet 还有一个子类 LinkedHashSet,LinkedHashSet 集合也是根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍 历LinkedHashSet 集合里的元素时,LinkedHashSet 将会按元素的添加顺序来访问集合里的元素。    LinkedHashSet 需要维护元素的插入顺序,因此性能略低于 HashSet 的性能,但在迭代访问 Set 里的全部元素时将有很好的性能,因为它以链表来维护内部顺序。    虽然 LinkedHashSet 使用了链表记录集合元素的添加顺序,但 LinkedHashSet 依然是 HashSet,因此它依然不允许集合元素重复(由哈希表保证唯一性,链表保证存取一致)。

1.4 TreeSet 集合

   TreeSet 是 SortedSet 接口的实现类,TreeSet可以确保集合元素处于排序状态。

1.4.1 常用方法

方法名

说明

Comparator comparator( )

如果 TreeSet 采用了定制排序,则该方法返回定制排序所使用的 Comparator;如果 TreeSet 采用了自然排序,则返回 null

Object first( )

返回集合中的第一个元素

Object last( )

返回集合中的最后一个元素

Object lower(Object e)

返回集合中位于指定元素之前的元素

Object higher(Object e)

返回集合中位于指定元素之后的元素

1.4.2 注意

   如果把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口,否则程序将会抛出异常。


补充:可变参数

   在 JDK1.5 之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:修饰符 返回值类型 方法名(参数类型... 形参名){ } 底层使用数组实现,可以当作数组使用,完全等价与修饰符 返回值类型 方法名(参数类型[] 形参名){ }只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。

示例

代码语言:javascript
复制
public class ChangeArgs {
	public static void main(String[] args) {
		int[] arr = { 1, 4, 62, 431, 2 };
        // 传递数组
        System.out.println("传递数组: " + getSum(arr));
        // 传递数据
        System.out.println("传递数据: " + getSum( 1, 4, 62, 431, 2 ));
	}
	
	public static int getSum(int... arr) {
		int sum = 0;
		for (int a : arr) {
		    sum += a;
		}
		return sum;
	}
}
在这里插入图片描述
在这里插入图片描述

注意   ♜ 一个参数列表只能由一个可变参数   ♜ 如果由多个参数,可变参数位于最后

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/04/15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1 Set 接口
  • 1.2 HashSet 集合
    • 1.2.1 HashSet 的特点
      • 1.2.2 示例
        • 1.2.2 注意事项
        • 1.3 LinkedHashSet 集合
        • 1.4 TreeSet 集合
          • 1.4.1 常用方法
            • 1.4.2 注意
            • 补充:可变参数
            相关产品与服务
            对象存储
            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档