Set 接口及其常用方法

悠悠 2024-03-16 19:48 167阅读 0赞

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

  1. 不允许重复元素:Set接口的实现类不会包含重复的元素。更正式地说,不包含任何一对使得e1.equals(e2)成立的元素e1e2,并且最多只能有一个null元素。当尝试添加重复元素时,添加操作将被忽略。
  2. 无序性:Set接口取出元素的顺序和添加元素的顺序不一致(但是每次取出的顺序是固定的),即无法通过索引访问Set中的元素。

Set接口的常用实现类有HashSetTreeSetLinkedHashSet。可以使用迭代器和增强 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. public Person() {
  4. }
  5. public Person(String name) {
  6. this.name = name;
  7. }
  8. public String getName() {
  9. return name;
  10. }
  11. public void setName(String name) {
  12. this.name = name;
  13. }
  14. @Override
  15. public boolean equals(Object o) {
  16. if (this == o) return true;
  17. if (o == null || getClass() != o.getClass()) return false;
  18. Person person = (Person) o;
  19. return name.equals(person.name);
  20. }
  21. @Override
  22. public int hashCode() {
  23. return Objects.hash(name);
  24. }
  25. @Override
  26. public String toString() {
  27. return "Person{" +
  28. "name='" + name + '\'' +
  29. '}';
  30. }
  31. }
  32. public class TestModifyValue() {
  33. public static void main(String[] args) {
  34. Set set = new HashSet();
  35. // 创建 3 个 Person 实例,其中 rose1.equals(rose2) 成立
  36. Person jack = new Person("Jack");
  37. Person rose1 = new Person("Rose");
  38. Person rose2 = new Person("Rose");
  39. // 将其添加到 set 中
  40. set.add(jack);
  41. set.add(rose1);
  42. set.add(rose2);
  43. // 可以看到只添加成功一个姓名为 Rose 的 Person 实例,其应为 rose1。
  44. System.out.println("set = " + set); // set = [Person{name='Rose'}, Person{name='Jack'}]
  45. // 将 set 添加到自身中,未添加成功
  46. set.addAll(set);
  47. System.out.println("set = " + set); // set = [Person{name='Rose'}, Person{name='Jack'}]
  48. // 将 rose1 的 name 属性修改为 Jack
  49. rose1.setName("Jack");
  50. System.out.println(rose1.equals(jack)); // true
  51. // 可以看到此时 set 集合中仍有两个对象,其 equals() 方法比较结果相同。
  52. System.out.println("set = " + set); // set = [Person{name='Jack'}, Person{name='Jack'}]
  53. }
  54. }

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. }

发表评论

表情:
评论列表 (有 0 条评论,167人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Set 接口及其方法

    `Set`接口是`Collection`接口的一个子接口,其主要特点如下: 1. 不允许重复元素:`Set`接口的实现类不会包含重复的元素。更正式地说,不包含任何一对使得`