Java——集合框架(Set)

简介: Java——集合框架(Set)

5 Set


5.1 Set 特点和基本操作


Set 接口的特点是元素不可以重复,无顺序


Set 接口中所有的操作都继承自 Collection 接口,也就是说,Set 接口没有自己特有的操作,其所有操作都来源于父接口 Collection。因此,它具有Collection 接口中定义的那些诸如 add、remove 等方法。


特别要注意的是,由于 Set 集合中的元素没有顺序,因此 Set 集合中的元素没有下标的概念。因此,和 List 接口不同,Set 接口中没有定义与下标相关的操作。


5.2 遍历


先介绍一个 Set 接口的实现类,HashSet。我们利用这个类来测试 Set 接口的遍历。


Set 接口中没有跟下标相关的方法,也就是说,Set 接口中没有类似 List 接口中的 get方法,因此,无法使用跟下标紧密联系的 for 循环遍历。但是,Set 接口可以使用迭代遍历。Collection 接口中定义了 iterator 方法,因此 Set 接口中也包含了这个方法。对于 Set 集合来说(尤其是 JDK1.5 以前的版本),只能采用迭代器的方式来遍历。

public class TestSet {
    public static void main(String[] args) {
        Set set = new HashSet();
        set.add("hello");
        set.add("world");
        set.add("java");
        //加入重复元素是,add 方法会返回 false
        set.add("hello");
        //迭代遍历
        Iterator iter = set.iterator();
        while(iter.hasNext()){
            Object value = iter.next();
            System.out.println(value);
        }
    }
}

要注意的是,迭代遍历输出的结果为:



hello


java


world


注意到对 set 调用了两次 add(“hello”)方法,但是输出结构只有一个 hello 字符串。同时,注意到输出结果的排列顺序与加入 set 的顺序完全无关。这就是 Set 集合的特点:元素无顺序,不可以重复。


5.3 实现类


对于 Set 集合的基本操作,相对而言比较容易掌握。对于 Set 接口而言,比较难掌握的地方在于 Set 接口的实现类相关内容。下面这部分内容是学习 Set 接口的重点。


HashSet 实现了 Set 接口,因此要求元素不可以重复。那么,HashSet 是怎么来判断元素是否可以重复的呢?


总结一下,如果要正常使用 HashSet 存放对象,为了保证对象的内容不重复,则要求这个对象满足:


1. 覆盖 equals 方法。要求相同的对象,调用 equals 方法返回 true。


2. 覆盖 hashCode 方法。要求,相同对象的 hashCode 相同,不同对象的 hashCode 尽量不同。

import java.util.*;
class Student{
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = 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;
    }
    public int hashCode() {
        return age + name.hashCode(); 
    }
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Student stu = (Student) obj;
        if ( (this.age == stu.age)&& (this.name.equals(stu.name)) ){
            return true;
        }else{
                return false;
        }
    }
    public String toString(){
        return name + " " + age;
        }
     }
    public class TestHashSet {
        public static void main(String[] args) {
            Set set = new HashSet();
            set.add(new Student("Tom", 18));
            set.add(new Student("Jim", 20));
            set.add(new Student("Fred", 22));
            set.add(new Student("Tom", 18));
            Iterator iter = set.iterator();
            while(iter.hasNext()){
                System.out.println(iter.next());
            }
    }
}

输出结果如下:


Fred 22


Jim 20


Tom 18


注意,add()方法被调用了四次,但是遍历 set 集合时,只读到了三个元素。


5.3.2 LinkedHashSet


HashSet 的特点是元素不可重复且元素无顺序。某些情况下,我们依然需要元素不可以重复,但是希望按照我们加入 Set 的先后顺序来加入这些元素。这个时候,我们就可以使用LinkedHashSet。

import java.util.*;
public class TestLinkedHashSet {
     public static void main(String args[]){
         Set set = new LinkedHashSet();
         set.add("hello");
         set.add("world");
         set.add("java");
         set.add("hello");
         Iterator iter = set.iterator();
         while(iter.hasNext()){
             System.out.println(iter.next());
         }
     }
}

输出结果如下:


hello


world


java


我们可以看到,字符串的打印顺序和它们添加到 LinkedHashSet 中的顺序是一致的。同时,hello 字符串被添加了两次,但只打印了一次。要注意的是,如果要使用 LinkedHashSet 的话,也必须正确的覆盖对象的 hashCode 和equals 方法。


相关文章
|
6天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
1天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
21天前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
28 5
|
18天前
|
Java 数据库连接 Apache
Java进阶-主流框架总结与详解
这些仅仅是 Java 众多框架中的一部分。每个框架都有其特定的用途和优势,了解并熟练运用这些框架,对于每一位 Java 开发者来说都至关重要。同时,选择合适框架的关键在于理解框架的设计哲学、核心功能及其在项目中的应用场景。随着技术的不断进步,这些框架也在不断更新和迭代以适应新的开发者需求。
34 1
|
22天前
|
索引 Python 容器
为什么Python中会有集合set类型?
为什么Python中会有集合set类型?
|
21天前
|
存储 Java 程序员
Java中的集合框架:从入门到精通
【8月更文挑战第30天】在Java的世界里,集合框架是一块基石,它不仅承载着数据的存储和操作,还体现了面向对象编程的精髓。本篇文章将带你遨游Java集合框架的海洋,从基础概念到高级应用,一步步揭示它的奥秘。你将学会如何选择合适的集合类型,掌握集合的遍历技巧,以及理解集合框架背后的设计哲学。让我们一起探索这个强大工具,解锁数据结构的新视角。
|
20天前
|
存储 算法 Java
Java中的集合框架深度解析与实践
【8月更文挑战第31天】在Java编程的海洋中,集合框架扮演着不可或缺的角色。本文将带你领略Java集合框架的魅力,从理论到实践,深入浅出地探索List、Set和Map等核心接口的使用技巧。我们将通过具体代码示例,展示如何在日常开发中高效运用这些工具,让你的代码更加优雅和高效。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往Java集合世界的大门。
|
20天前
|
存储 人工智能 Java
JAVA集合
【8月更文挑战第31天】
|
30天前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
30天前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。