A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李坏 中级黑马   /  2014-5-16 12:59  /  1891 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 李坏 于 2014-5-17 19:39 编辑

为什么arraylist不能通过重写hashCode、equals来去除重复?hashCode和equals为啥要同时重写?什么时候用toString方法!?:Q

求知道的童鞋详细解答 O(∩_∩)O谢谢

8 个回复

倒序浏览
hashCode和equals是专门针对hash集合作用的。如HashSet等,原理是这样,当你初始化一个哈希集合时就产生了一个hash值,然后你要存储进集合的元素如果覆写了hashCode方法,那么这两处产生的哈希值实际是一样的,因为都是同一台电脑,所以覆写hashCode仅仅是为了添加进哈希集合更有效率,即找对应区域添加,而equals方法是对象添加进哈希集合后,总得判断重复吧,比如把你分配到一个年段的1班,总得判断1班有没同名字的人吧。
回复 使用道具 举报
底层的数据结构不同,调用的方法也不一样的说。
回复 使用道具 举报
请你记住:需要复写hashCode和equals方法的集合 其底层数据结构必须是哈希表
哈希表是根据哈希值的不同将元素进行分类存储  哈希值其实也就是内存地址的意思
我们只要知道元素的哈希值 就知道它存在哪个内存中  也就是根据内存地址去访问内存中的数据
为什么两个方法要同时复写了?
通常采用哈希表为数据结构的集合就两种 HashSet  HashMap
这两个集合一个很相似的地方就是元素唯一 不可重复   
有可能出现这种情况 虽然元素的内存地址不一样  但它的内容却是一样的  
因此为了保证唯一性 就是如果哈希值一样  再判断内容是否相同
举个例子
  1. package cn.heima.test;

  2. import java.util.HashSet;

  3. class Person
  4. {
  5.         String name;
  6.         int age;
  7.         Person(String name,int age)
  8.         {
  9.                 this.name=name;
  10.                 this.age=age;
  11.         }
  12.        
  13.         public String toString()
  14.         {
  15.                 return "name:"+name+"age:"+age;
  16.         }
  17. }
  18. public class Demo {

  19.         public static void main(String[]args)
  20.         {
  21.                 Person p1=new Person("张三",12);
  22.                 Person p2=new Person("张三",12);
  23.                 HashSet<Person> hs=new HashSet<Person>();
  24.                 hs.add(p1);
  25.                 hs.add(p2);
  26.                 System.out.println(hs);
  27.                 //结果:[name:张三age:12, name:张三age:12]
  28.                 //两个相同的人怎么都放进一个集合之中
  29.         }

  30. }
复制代码

toString这个方法在System.out.println();中会自动调用打印对象的toString方法

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
为什么arraylist不能通过重写hashCode、equals来去除重复?hashCode和equals为啥要同时重写?什么时候用toString方法!?

因为ArrayList集合的底层数据结构是数组。而hashCode和equals方法是hashSet集合和hashMap集合中判断元素是否存在的方法。
而ArrayList集合判断元素是否重复的方法是通过equals
toString方法是将对象转换成字符串,
例如:
class Student4
{
        private String name;
        private int age;
        public String setName()
        {
                return name;
        }
        public int setAge()
        {
                return age;
        }
       
        Student4(String name,int age)
        {
                this.name = name;
                this.age = age;
        }
       
        //覆盖toString方法
        public String toString()
        {
                return "name:"+name+"...age:"+age;
        }
}

public class Text4 {
       
        public static void main(String[]args)
        {
                Student4 s = new Student4("zhangSan",22);
                System.out.println(s);
        }

}
输出结果是:name:zhangSan...age:22

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
凶凶 ,ArrayList   本来就可以存重复的元素的。
童鞋,介个问题啊,List  是有序而可重复,Set 是无序而不可重复的。   这个要记清楚了。

hashCoude,和equals  为什么要一起覆盖。
首先覆盖 hashCoude 方法的目的就是返回一个特殊的哈希值代码,为什么要返回特殊的哈希代码地址值,
主要是考虑到哈希地址值容易出现重复的问题,
我记得老师讲了一个很例子,顺便提一下,
说存入一个 李四,20岁,存一个张三,40岁,
假设李四的哈希值是40,张三的哈希值是20  那么,他们相加会出现相等的情况
所以视频里,老师的代码给年纪乘以的一个数,

覆盖equals 方法是指定一个默认的排序方案。

因为 Set  是无序的排序,所以要指定一个默认的排序。

随便再提一下 比较器,

这个类写好以后会有一个默认的排序, 看起来很直观,
如果新的需求需要另外的一种排序方案,
老师不建议我们去修改源代码,
而使用比较器来定义一个新的排序方案。

最后是toString  方法。

在你类里,你覆盖一个该方法,
比如
  1. public String toString(){
  2.                 return name+"...."+age;
  3.         }
复制代码

就能把  name 和age  直接转换成一个字符串, 输出打印的时候方便。
有些时候toString()真是好用,这个代码我多写几次后的感觉

评分

参与人数 1技术分 +1 收起 理由
轻语。 + 1

查看全部评分

回复 使用道具 举报
wyqs92 中级黑马 2014-5-16 23:27:56
7#
因为ArrayList 的底层是数组结构的,而hashcode和equals方法是Hashset中的方法,其底层是哈希表。而ArrayList 中中并没有这两种 方法。那为什么我们在用HashSet时 为什么要覆盖这两种方法了?那是因为在hashset中,它存数据会用到哈希表,将要存储的元素通过哈希算法,即hashcode方法。当存储的元素算出的哈希值相同的时候,就会通过equals方法比较内容是否相同。而ArrayList 的底层不是哈希表所以不能重写去重复。
tostring什么时候用?tostring是将对象转换成字符串,所以如果你要得到字符串形式的结果,就可以用tostring。如果你不转换,可能输出的就是对象的地址,即它的哈希值。
回复 使用道具 举报
本帖最后由 郭帅帅 于 2014-5-16 23:45 编辑

首先,你得明确一个前提就是,arraylist底层是数组,存放的元素能重复。要是不想有重复就用其他容器,用list本来就是错误的选择,再用hashCode,equals更是多此一举。当容器是hash表的时候,会重写那两个方法,能去除重复元素。至于什么时候用toString,得视情况而定
回复 使用道具 举报
这是 底层数据结构决定的。ArrayList底层是数组存取没必要比较去掉重复 想要去掉重复可以复写equals()。2重写hashcode,equals.是在是底是hash表的数据结构时复写, 因为原有的equals 比较是比较hash,“hash表”允许重复的hash值存入。 所以要复写hashCode,equals。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马