Java学习日记——Set接口

特点

无序、值唯一

实现类

HashSet类

特点

无序

数据结构

创建HashSet时,其构造方法创建维护了一个HashMap来进行存储,元素值保存在HashMap的key位置

常用方法

其常用方法基本与List接口相同,详情可查看我的上一篇博客“Java学习日记——List接口

LinkedHashSet

特点

有序

数据结构

创建LinkedHashSet时,其构造方法调用父类构造方法,在内部创建维护了一个LinkedHashMap,用于维持元素的有序性

TreeSet类

特点

可排序

数据结构

创建TreeSet时,其构造方法创建了一个TreeMap,用于保存元素。由于TreeMap可以自动排序,所以TreeSet中的元素也按照排序特点保存。

TreeSet对其可排序举例如下

//Book类
import java.util.Objects;

public class Book implements Comparable<Book>{

    private String bookName; // 书名
    private int pageSize; // 页数
    private double price; // 价格

    public Book() {

    }

    public Book(String bookName, int pageSize, double price) {
        super();
        this.bookName = bookName;
        this.pageSize = pageSize;
        this.price = price;
    }


    public String getBookName() {
        return bookName;
    }
    public void setBookName(String bookName) {
        this.bookName = bookName;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", pageSize=" + pageSize +
                ", price=" + price +
                '}';
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.bookName,this.pageSize,this.price);
    }

    @Override
    public boolean equals(Object obj) {
        if (this==obj){
            return true;
        }
        if (obj instanceof Book){
            Book book = (Book)obj;
            return this.bookName.equals(bookName)&&this.pageSize== book.pageSize&&this.price== book.price;
        }
        return false;
    }


    @Override
    public int compareTo(Book o){
        if (this.pageSize==o.pageSize){
            return this.bookName.compareTo(o.bookName);
        }
        return this.pageSize-o.pageSize;
    }
}
//测试类demo
import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;

public class demo {
    public static void main(String[] args) {
        TreeSet<Book> bookSet=new TreeSet<>(new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                if (o1.getPrice()>o2.getPrice()){
                    return 1;
                } else if (o1.getPrice()<o2.getPrice()) {
                    return -1;
                }
                return 0;
            }
        });
        bookSet.add(new Book("我的高密", 1901, 177.5));
        bookSet.add(new Book("射雕英雄传", 2374, 66.51));
        bookSet.add(new Book("平凡的世界", 2110, 51.75));
        bookSet.add(new Book("葫芦娃大战奥特曼", 1875, 135.49));
        bookSet.add(new Book("鲁滨逊漂流记", 3694, 99.99));
        bookSet.add(new Book("海底两万里", 1120, 33.15));
        bookSet.add(new Book("海底两万里一千里", 1120, 34.15));

        for (Book book:bookSet){
            System.out.println(book);
        }

    }
}
/*
输出内容
Book{bookName='海底两万里', pageSize=1120, price=33.15}
Book{bookName='海底两万里一千里', pageSize=1120, price=34.15}
Book{bookName='平凡的世界', pageSize=2110, price=51.75}
Book{bookName='射雕英雄传', pageSize=2374, price=66.51}
Book{bookName='鲁滨逊漂流记', pageSize=3694, price=99.99}
Book{bookName='葫芦娃大战奥特曼', pageSize=1875, price=135.49}
Book{bookName='我的高密', pageSize=1901, price=177.5}
*/

常见问题

Set集合如何过滤重复元素?

1.调用元素HashCode方法来获取元素的哈希值

2.通过哈希值在对于的集合中查找是否有相同的哈希值

3.若找到相同的哈希值,则调用equals()方法来对元素的内容进行比较,若不同则添加,相同则不添加

4.若找不到相同的哈希值,则直接将该元素添加

通过以上四个步骤,确保了Set集合中无重复元素

为什么重写hashCode()时,必须重写equals()?

在上一个问题回答中提到,在Set集合中进行存储新元素时,首先通过调用元素的hashcode()方法来在要插入的集合中进行查找,如果在集合中未查找到该哈希值,则直接存储。但是对于哈希值来说他是根据元素来计算出来的整型数字,而int是有范围的,它的范围是-2,147,483,648(-2^31)到 2,147,483,647(2^31 - 1),共计约 21 亿个不同的整数。但是元素在理论上是无限的,所以int型数字如果一一匹配各个元素,肯定会有两个甚至多个元素拿去到的int型数字是相同的,也就是说,一个hashcode值可能对应多个(甚至是无数个)元素。例如:

public static void main(String[] args) {
        String s1="通话";
        String s2="重地";
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
    }
/*
输出
1179395
1179395
*/

可见s1和s2的哈希值是相同的,当一个集合中存入了s1内容为“通话”时,在未重写equals方法时,再想存入s2时,JVM直接判断集合中有相同的哈希值,则认为元素相同,为了保持集合的不重复性,则不会存储s2,所以需要对equals方法进行重写来判断输入的s2与s1的内容是否相同。

为什么会产生哈希冲突?

在回答上述问题中已经提到

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值