Set 接口及其常用方法

打印 上一主题 下一主题

主题 935|帖子 935|积分 2805

Set 接口基本介绍

Set接口是Collection接口的一个子接口,其主要特点如下:

  • 不允许重复元素:Set接口的实现类不会包含重复的元素。更正式地说,不包含任何一对使得e1.equals(e2)成立的元素e1和e2,并且最多只能有一个null元素。当尝试添加重复元素时,添加操作将被忽略。
  • 无序性:Set接口取出元素的顺序和添加元素的顺序不一致(但是每次取出的顺序是固定的),即无法通过索引访问Set中的元素。
Set接口的常用实现类有HashSet、TreeSet和LinkedHashSet。可以使用迭代器和增强 for 循环遍历元素,但是不能使用普通 for 循环(不能使用索引)。下面的代码以其实现类HashSet演示Set接口的特点。
  1. public class TestSet() {
  2.   public static void main(String[] args) {
  3.     Set set = new HashSet();
  4.     set.add("Phoebe");
  5.     set.add("Monica");
  6.     set.add("Phoebe"); // 重复
  7.     set.add("Ross");
  8.     set.add("Chandler");
  9.     set.add("Rachel");
  10.     set.add(null);
  11.     set.add(null); // 再次添加 null
  12.     // 10 次输出结果均为:set=[Phoebe, null, Rachel, Ross, Chandler, Monica]
  13.     // 重复的 Phoebe 和 null 都只输出了一个,
  14.     // 取出顺序和添加顺序不一致但每次取出顺序都是相同的。
  15.     for (int i = 0; i < 10; i++) {
  16.       System.out.println("set=" + set);
  17.     }
  18.   }
  19. }
复制代码
注意:如果Set集合的元素是可变对象时,必须要小心。如果以影响equals()方法比较结果的方式修改Set中的元素的值,集合的行为是未指定的。这种情况的特例是Set不能将自身作为元素。以下以一个简单的 Person 类来测试修改HashSet中元素的值使得两个元素equals()方法比较结果相同时的情况。
  1. public class Person {
  2.   private String name;
  3.   
  4.   public Person() {
  5.   }
  6.   public Person(String name) {
  7.     this.name = name;
  8.   }
  9.   public String getName() {
  10.     return name;
  11.   }
  12.   public void setName(String name) {
  13.     this.name = name;
  14.   }
  15.   @Override
  16.   public boolean equals(Object o) {
  17.     if (this == o) return true;
  18.     if (o == null || getClass() != o.getClass()) return false;
  19.     Person person = (Person) o;
  20.     return name.equals(person.name);
  21.   }
  22.   @Override
  23.   public int hashCode() {
  24.     return Objects.hash(name);
  25.   }
  26.   @Override
  27.   public String toString() {
  28.     return "Person{" +
  29.       "name='" + name + '\'' +
  30.       '}';
  31.   }
  32. }
复制代码
  1. public class TestModifyValue() {
  2.   public static void main(String[] args) {
  3.     Set set = new HashSet();
  4.    
  5.     // 创建 3 个 Person 实例,其中 rose1.equals(rose2) 成立
  6.     Person jack = new Person("Jack");
  7.     Person rose1 = new Person("Rose");
  8.     Person rose2 = new Person("Rose");
  9.     // 将其添加到 set 中
  10.     set.add(jack);
  11.     set.add(rose1);
  12.     set.add(rose2);
  13.    
  14.     // 可以看到只添加成功一个姓名为 Rose 的 Person 实例,其应为 rose1。
  15.     System.out.println("set = " + set); // set = [Person{name='Rose'}, Person{name='Jack'}]
  16.     // 将 set 添加到自身中,未添加成功
  17.     set.addAll(set);
  18.     System.out.println("set = " + set); // set = [Person{name='Rose'}, Person{name='Jack'}]
  19.     // 将 rose1 的 name 属性修改为 Jack
  20.     rose1.setName("Jack");
  21.     System.out.println(rose1.equals(jack)); // true
  22.     // 可以看到此时 set 集合中仍有两个对象,其 equals() 方法比较结果相同。
  23.     System.out.println("set = " + set); // set = [Person{name='Jack'}, Person{name='Jack'}]
  24.   }
  25. }
复制代码
Set 接口常用方法

Set接口和List接口一样,也是Collection接口的子接口,因此常用方法和Collection接口一样。但需要注意由于Set接口不包含重复元素,所以addAll()方法的参数也是Set时,addAll操作会有效地修改该集合,使其值为两个集合的并集
  1. public class SetAddAll() {
  2.   public static void main(String[] args) {
  3.     Set set = new HashSet();
  4.     set.add("Phoebe");
  5.     set.add("Monica");
  6.     set.add("Ross");
  7.     System.out.println("set = " + set); // set = [Phoebe, Ross, Monica]
  8.     Set set1 = new HashSet();
  9.     set1.add("Phoebe");
  10.     set.add("Chandler");
  11.     set.addAll(set1);
  12.     System.out.println("set = " + set); // set = [Phoebe, Ross, Chandler, Monica]
  13.   }
  14. }
复制代码
Set 接口遍历元素方式

Set接口遍历元素的方式和Collection接口的一样,可以使用迭代器和增强 for 循环来遍历元素,但不能通过索引的方式来遍历元素。
  1. public class SetThroughElements() {
  2.   public static void main(String[] args) {
  3.     Set set = new HashSet();
  4.     set.add("Phoebe");
  5.     set.add("Monica");
  6.     set.add("John");
  7.     System.out.println("---使用迭代器---");
  8.     Iterator iterator = set.iterator();
  9.     while (iterator.hasNext()) {
  10.       Object obj =  iterator.next();
  11.       System.out.println("obj = " + obj);
  12.     }
  13.     System.out.println("---使用增强 for---");
  14.     for (Object o :set) {
  15.       System.out.println("o = " + o);
  16.     }
  17.     // 不能使用普通 for 循环,因为 Set 不支持索引
  18.   }
  19. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

郭卫东

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表