【集合框架】4. Set容器

本文深入探讨了Java中Set容器的两种实现方式:HashSet与TreeSet。详细解释了HashSet如何通过散列表存储元素,并确保元素唯一性;同时介绍了TreeSet如何利用红黑树实现排序存储。此外,还提供了实例代码帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

集合框架


4. Set容器

4.1 HashSet接口

  • HashSet扩展AbstractSet并且实现Set接口
  • HashSet使用散列表(又称哈希表)进行存储
  • 构造方法
    • HashSet()
    • HashSet(Collection c)
    • HashSet(int capacity)
    • HashSet(int capacity,float fillRatio)
  • HashSet没有定义任何超过它父类和接口的方法
  • 散列集合没有确保其元素的顺序,因为散列处理通常不参与排序

HashSet源代码分析——HashSet操作的是HashMap的键
- HashSet调用的构造方法里创建了一个HashMap:

public HashSet() { 
       map = new HashMap<>();
   }
  • 给HashSet添加元素实际上就是添加到HashMap的键,值不需要
public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
  • HashSet的size就是HashMap的size,HashMap是空的,HashSet就是空的
public int size() {
        return map.size();
    }

    public boolean isEmpty() {
        return map.isEmpty();
    }
  • HashSet的迭代器是HashSet的所有键的迭代器,包含contains是去HashMap中查询有没有指定的key:
public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

    public boolean contains(Object o) {
        return map.containsKey(o);
    }

Dem1:HashSet的基本用法

package Collection;

import java.util.HashSet;

public class HashSetDemo1 {
    public static void main(String[] args){
        HashSet<String> data=new HashSet<String>();
        data.add("Mandy");
        data.add("Anne");
        //add()方法返回一个boolean值,判断是否添加成功
        System.out.println(data.add("Sarah"));
        data.add("Lara");
        //Sarah重复出现了,add()方法返回false,说明Set不能存储重复的值
        System.out.println(data.add("Sarah"));
        System.out.println(data);

        HashSet<sstudent> stu=new HashSet<sstudent>();
        /*在使用默认的equals方法时,new出来的两个“Mandy”被视为不同的对象,在HashSet中都能成功添加
        重写sstudent的equals方法,让name和age对应相等的对象比较后返回ture,HashSet就只会存放一个*/
        stu.add(new sstudent("Mandy",20));
        System.out.println(stu.add(new sstudent("Mandy",20)));
        stu.add(new sstudent("Jenny",20));
        System.out.println(stu.size());
    }
}
class sstudent{
    private String name;
    private int age;
    public sstudent(String name, int age) {
        super();
        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;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        sstudent other = (sstudent) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

}

4.2 TreeSet接口:

  • TreeSet为使用树来进行存储的Set接口提供了一个工具,对象按升序排序存储,访问和检索很快
  • 在存储了大量的需要进行快速检索的排序信息的情况下,TreeSet是一个很好的选择
  • 构造方法
    • TreeSet()
    • TreeSet(Collection c)
    • TreeSet(Comparator comp)
    • TreeSet(SortedSet ss)
  • TreeSet没有定义任何超过它父类和接口的方法
  • 散列集合没有确保其元素的顺序,因为散列处理通常不参与排序
    • TreeSet调用的构造方法里创建了一个TreeMap:
public TreeSet() {
        this(new TreeMap<E,Object>());
    }
  • 给TreeSet添加元素实际上就是添加到TreeMap的键,值不需要
public boolean add(E e) {
        return m.put(e, PRESENT)==null;
    }

Demo2:TessSet的基本用法

package Collection;

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetDemo {

    public static void main(String[] args) {
        TreeSet<Pperson> ps=new TreeSet<Pperson>(new Comparator<Pperson>(){
            @Override
            public int compare(Pperson o1, Pperson o2){
            if(o1.getAge()-o2.getAge()>0){
                return 1;
            }else if(o1.getAge()-o2.getAge()<0){
                return -1;
            }else
                return 0;   
            }
        });
        ps.add(new Pperson("Anne",18));
        ps.add(new Pperson("Rose",20));
        ps.add(new Pperson("Cara",12));
        ps.add(new Pperson("Bony",19));
        Iterator<Pperson> it=ps.iterator();
        while(it.hasNext()){
            Pperson p=it.next();
            System.out.println(p.getName()+"--"+p.getAge());
        }
    }
}
class Pperson /*implements Comparable<Pperson>*/{
    private String name;
    private int age;
    public Pperson(String name, int age) {
        super();
        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;
    }
    /*@Override
    public int compareTo(Pperson o){
        if(this.age-o.age>0){
            return 1;
        }else if(this.age-o.age<0){
            return -1;
        }else
            return 0;
    }*/
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值