java Set HashSet详解,java初级面试笔试题


我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家。
扫描二维码或搜索下图红色VX号,加VX好友,拉你进【程序员面试学习交流群】免费领取。也欢迎各位一起在群里探讨技术。
推荐文章:Java 面试知识点解析Mysql优化技巧(数据库设计、命名规范、索引优化

 

Set集合

 

就像把对象随意扔进罐子里,无法记住元素的添加顺序。Set某种程度就是Collection,方法没有不同,只是行为稍微不同,(不允许重复元素),如果一定要往里加两个相同元素,添加失败add()返回false;

上面的Set的一些共同点,Hashset,TreeSet,EunmSet三个实现类还各有特色。

依次介绍下

Hashset

判断Hashset 集合里的两个对象相等,过两关,equal()比较相等,对象的hashcode()也相等

为什么还得比较对象的hashcode()?

Hashset 集合收进一个对象时,会调用对象的hashcode()得到其Hashcode值来决定他的存储位置。所以,即使是equal()比较相等的两个对象,hashcode不同,存放在hashset里的位置不同,依然能把这两个对象添加成功。

注意:把对象装进hashset时,如果要重写equals方法,也得重写hashcode 方法,因为equals()相等的两对象hashcode 也是相同的。

提问:hashcode()对hashset是很重要的吗?

答:hash算法是快速查找被检索的对象。通过对象的hashcode定位集合里的对象的存储位置。定位该元素。对比下,数组是存储一组元素最快的数组结构,数组通过索引找到它的组员,通过索引能计算元素在内存里的存储位置。

但是为嘛有了数组,还用hashset呢?数组也有局限性,索引是连续的,而且长度不可变。

hashset有了hashcode,所以能快速定位对象位置,而且任意增加对象。

重写hashcode() 注意java.lang.Object中对hashCode的约定:

两个对象通过equals()比较相等时,他们的hashcode 也应该是一样的。

程序运行过程中,同一个对象多次调用hashcode方法返回应该是一样的。

如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么在两个对象中的任一对象上调用 hashCode 方法不一定会生成不同的整数结果。但是,为不相等的对象生成不同整数结果可以提高哈希表的性能。 实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。

 

向hashset里添加了一个可变对象后时,要注意:如果后面的程序修改了这个可变对象的实例变量时,可能会导致他与集合里的其他元素相同,即两个对象equals返回true,hashcode也相同。导致hashSet不能正确操作那些元素。

补充了解下,可变对象:创建后,对象的属性值可能会变,也就是说,创建后对象的hash值可能会改变。

举例:对象MutableKey的键在创建时变量 i=10 j=20,哈希值是1291。然后我们改变实例的变量值,该对象的键 i 和 j 从10和20分别改变成30和40。现在Key的哈希值已经变成1931。显然,这个对象的键在创建后发生了改变。所以类MutableKey是可变的。

下面代码是hashset里添加了一个可变对象例子,

可看出,hashset已经添加了几个成员后,修改一个成员的实例变量,会得到里面有相同的成员,因此是不对的。

但是,对最后一行,不能准确访问成员这个。有点疑问,待解决。

 

package Test01;

import java.util.HashSet;

import java.util.Iterator;

class mutClass{

    public int count;

    public  mutClass(int count) {

        this.count =count;

    }

    public  boolean equals(Object obj) {

        if(this == obj) {

            return true;

        }

        if(obj != null && obj.getClass() == mutClass.class) {

            mutClass m =(mutClass) obj;

            return this.count == m.count;

        }

        return false;

    }

    public  int hashcode() {

        return this.count;

    }

    public String toString() {

        return "试试mutClass[count=" + count + "]";

    }

    

}

public class TestHashSet {

   @SuppressWarnings("unchecked")

public static void main(String[] args){

       HashSet testHashSet =new HashSet();

       

       mutClass a = new mutClass(3);

       mutClass b = new mutClass(1);

       mutClass c = new mutClass(-9);

       mutClass d = new mutClass(9);

       testHashSet.add(a);

       testHashSet.add(b);

       testHashSet.add(c);

       testHashSet.add(d);

        System.out.println("第一次"+testHashSet);

        Iterator iterator =testHashSet.iterator();

       mutClass first = (mutClass) iterator.next();

       first.count=9;

      /* testHashSet.remove(new mutClass(3));

       testHashSet.remove(b);    //与上一行的区别

*/       System.out.println("第二次"+testHashSet);

        System.out.println(new mutClass(-9) == new mutClass(-9));

       System.out.println("第四次"+testHashSet.contains(new mutClass(-9)));

    }

}

 

hashset不能保证添加成员的顺序,和自己的顺序是一样的,但是引入了一个LinkedHashSet子类,使得它能和hashset一样,靠hashcode 找到他的存储位置,又能维护添加成员的顺序,内部靠一个链表实现,迭代访问集合时有很好的性能。

 


转载:https://www.cnblogs.com/yizhizhangBlog/p/9258532.html

推荐内容:
java面试题
Java序列化机制原理
详解Java的自动装箱与拆箱(Autoboxing and unboxing)
Java 最常见的 200+ 面试题汇总
JAVA多线程和并发基础面试问答
面试题--JAVA中静态块、静态变量加载顺序
50道Java线程面试题汇总
Java集合---面试题
Java工程师面试题整理[社招篇]
java面试题:Spring

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值