最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

Set 接口及其常用方法

来源:博客园


【资料图】

Set 接口基本介绍

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

  1. 不允许重复元素:Set接口的实现类不会包含重复的元素。更正式地说,不包含任何一对使得e1.equals(e2)成立的元素e1e2,并且最多只能有一个null元素。当尝试添加重复元素时,添加操作将被忽略。

  2. 无序性:Set接口取出元素的顺序和添加元素的顺序不一致(但是每次取出的顺序是固定的),即无法通过索引访问Set中的元素。

Set接口的常用实现类有HashSetTreeSetLinkedHashSet。可以使用迭代器和增强 for 循环遍历元素,但是不能使用普通 for 循环(不能使用索引)。下面的代码以其实现类HashSet演示Set接口的特点。

public class TestSet() {  public static void main(String[] args) {    Set set = new HashSet();    set.add("Phoebe");    set.add("Monica");    set.add("Phoebe"); // 重复    set.add("Ross");    set.add("Chandler");    set.add("Rachel");    set.add(null);    set.add(null); // 再次添加 null    // 10 次输出结果均为:set=[Phoebe, null, Rachel, Ross, Chandler, Monica]    // 重复的 Phoebe 和 null 都只输出了一个,    // 取出顺序和添加顺序不一致但每次取出顺序都是相同的。    for (int i = 0; i < 10; i++) {      System.out.println("set=" + set);    }  }}

注意:如果Set集合的元素是可变对象时,必须要小心。如果以影响equals()方法比较结果的方式修改Set中的元素的值,集合的行为是未指定的。这种情况的特例是Set不能将自身作为元素。以下以一个简单的 Person 类来测试修改HashSet中元素的值使得两个元素equals()方法比较结果相同时的情况。

public class Person {  private String name;    public Person() {  }  public Person(String name) {    this.name = name;  }  public String getName() {    return name;  }  public void setName(String name) {    this.name = name;  }  @Override  public boolean equals(Object o) {    if (this == o) return true;    if (o == null || getClass() != o.getClass()) return false;    Person person = (Person) o;    return name.equals(person.name);  }  @Override  public int hashCode() {    return Objects.hash(name);  }  @Override  public String toString() {    return "Person{" +      "name="" + name + "\"" +      "}";  }}
public class TestModifyValue() {  public static void main(String[] args) {    Set set = new HashSet();        // 创建 3 个 Person 实例,其中 rose1.equals(rose2) 成立    Person jack = new Person("Jack");    Person rose1 = new Person("Rose");    Person rose2 = new Person("Rose");    // 将其添加到 set 中    set.add(jack);    set.add(rose1);    set.add(rose2);        // 可以看到只添加成功一个姓名为 Rose 的 Person 实例,其应为 rose1。    System.out.println("set = " + set); // set = [Person{name="Rose"}, Person{name="Jack"}]    // 将 set 添加到自身中,未添加成功    set.addAll(set);    System.out.println("set = " + set); // set = [Person{name="Rose"}, Person{name="Jack"}]    // 将 rose1 的 name 属性修改为 Jack    rose1.setName("Jack");    System.out.println(rose1.equals(jack)); // true    // 可以看到此时 set 集合中仍有两个对象,其 equals() 方法比较结果相同。    System.out.println("set = " + set); // set = [Person{name="Jack"}, Person{name="Jack"}]  }}

Set 接口常用方法

Set接口和List接口一样,也是Collection接口的子接口,因此常用方法和Collection接口一样。但需要注意由于Set接口不包含重复元素,所以addAll()方法的参数也是Set时,addAll操作会有效地修改该集合,使其值为两个集合的并集

public class SetAddAll() {  public static void main(String[] args) {    Set set = new HashSet();    set.add("Phoebe");    set.add("Monica");    set.add("Ross");    System.out.println("set = " + set); // set = [Phoebe, Ross, Monica]    Set set1 = new HashSet();    set1.add("Phoebe");    set.add("Chandler");    set.addAll(set1);    System.out.println("set = " + set); // set = [Phoebe, Ross, Chandler, Monica]  }}

Set 接口遍历元素方式

Set接口遍历元素的方式和Collection接口的一样,可以使用迭代器和增强 for 循环来遍历元素,但不能通过索引的方式来遍历元素。

public class SetThroughElements() {  public static void main(String[] args) {    Set set = new HashSet();    set.add("Phoebe");    set.add("Monica");    set.add("John");    System.out.println("---使用迭代器---");    Iterator iterator = set.iterator();    while (iterator.hasNext()) {      Object obj =  iterator.next();      System.out.println("obj = " + obj);    }    System.out.println("---使用增强 for---");    for (Object o :set) {      System.out.println("o = " + o);    }    // 不能使用普通 for 循环,因为 Set 不支持索引  }}

关键词: