黑马程序员技术交流社区

标题: HashSet问题 [打印本页]

作者: 四川男人    时间: 2014-4-19 00:34
标题: HashSet问题
本帖最后由 四川男人 于 2014-4-19 11:06 编辑

HashSet底层数据结构是hash表,对象的地址相同的时候,判断对象是否相同,对象不同也在当前地址保存下来,那么。如何读取出来呢?

作者: hhmm665544    时间: 2014-4-19 00:46
Iterator iterator=set.iterator();
                while(iterator.hasNext()){
                        System.out.println(iterator.next());
                }
作者: vtming    时间: 2014-4-19 01:11
同二楼。
另,楼主是不是想表达其他什么意思???
作者: 陈妙俊    时间: 2014-4-19 08:50
通过迭代器,然后遍历循环,建议楼主多看看毕老师关于集合框架视频,就会明白 的。
作者: 左拉    时间: 2014-4-19 09:05
其实楼主是不是想问:在HashSet中,怎么样判断一个对象是否相同呢?
判断一个对象相同必须通过hashCode和equals两个方法。所以这两个方法最好都要重写。
当使用hash表存储数据时,生成hashCode的时候可能生成一样的hashCode的值。

当两个对象的地址相同的时候(用==判断),两个对象肯定是相同的。
当两个对象equals()的值为true时,hashCode最好相同。
当两个对象hashCode相同时,他们不一定相互equals,最好的例子是字符串"BB"和"Aa"的equals方法比
较的结果肯定是不相等的,但是它们的hashCode方法返回值却相等。

参考String的hashCode源代码:
public int hashCode() {
int h = hash;
if (h == 0) {
    int off = offset;
    char val[] = value;
    int len = count;
            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
}


作者: Royvan    时间: 2014-4-19 09:05
hash结构中,每一个元素,都会有一个记录next的内存空间,元素刚存进去的时候,next中内容为null。
在HashSet对象中,如果存在hash值相同、对象不同的情况下,
就会在next空间内记录下一个相同hash值且不相等的对象。
这种情况,叫做”顺延“。
作者: 四川男人    时间: 2014-4-19 09:42
hhmm665544 发表于 2014-4-19 00:46
Iterator iterator=set.iterator();
                while(iterator.hasNext()){
                        System.out.println(iterator.next() ...

这种我知道,我想了解的是hash值相同,对象不同,在同一个hash值地址上保存,怎么找出来
作者: 四川男人    时间: 2014-4-19 09:53
Royvan 发表于 2014-4-19 09:05
hash结构中,每一个元素,都会有一个记录next的内存空间,元素刚存进去的时候,next中内容为null。
在HashS ...

怎么取?iterator.next();????
作者: 左拉    时间: 2014-4-19 10:22
四川男人 发表于 2014-4-19 09:53
怎么取?iterator.next();????

  1. import  java.util.Set;
  2. import  java.util.HashSet;
  3. import  java.util.Iterator;
  4. public class Test{
  5.    public static void main(String[] args){
  6.      Set<String> set=new HashSet<String>();
  7.     //添加测试数据
  8.     set.add("a");
  9.     set.add("b");
  10.     set.add("c");
  11.    //使用迭代器Iterator  Collection的子类都可以通过iterator()方法将集合中的数据存储到迭代器进行迭代输出;
  12.    Iterator<String> iter=set.iterator();
  13.    //通过循环判断是否有下一个元素
  14.    while(iter.hasNext()){
  15.        //如果有数据则取出来
  16.        String str=iter.next();
  17.        //输出数据;
  18.        System.out.println(str);
  19.    }
  20. }

  21. }
复制代码



关于Iterator:
迭代器(Iterator)模式,又叫做游标(Cursor)模式。GOF给出的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。从定义可见,迭代器模式是为容器而生。
来看下Java Collection中的迭代器是怎么实现的吧。迭代器角色,仅仅定义了遍历接口:
public interface Iterator
{
     boolean hasNext();
     Object next();
     void remove();
}

hashNext()判断是否存在下一个元素,可理解为指针,把Iterator里面的元素想象成数组。那么当前Iterato的指针指向第一个元素之前,也就是this.hashNext()判断第一个元素是否为空,如果不为空,它的next()值就是第一个元素,以此类推,通过循环判断就可以遍历所有的元素。
作者: 也许依然    时间: 2014-4-19 11:43
HashSet底层的数据结构是哈希表,在查找时,理想的情况是不经过任何比较,一次存取便能得到所查的记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使没个关键字和结构中一个唯一的存储位置相对应,这个对应关系f就是哈希函数。

HashSet是一个无序的集合,也就是存入和取出的顺序不一定一致,取出时是按照一定顺序的哈希值建立的表,按照表的顺序取出元素

当取出时,用到迭代器 Iterator ,迭代器就是一种取出的方式,为了方便使用,将其封装到了类的内部,可由集合对象调用
Iterator类有三个方法,next() , hasNext(), remove()
next方法可以取出下一个元素,hasNext方法用于判断是否还有元素可以迭代

代码演示:
  1. public static void main(String[] args){
  2.         HashSet<String> hs = new HashSet<String>();

  3.         hs.add("zhangsan");
  4.         hs.add("lisi");
  5.         hs.add("wangwu");

  6.         Iterator<String> it = hs.iterator();
  7.         while(it.hasNext()){
  8.                 String name = it.next();
  9.                 System.out.println(name);
  10.         }
  11. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2