黑马程序员技术交流社区

标题: 菜鸟:ArrayList 与hashSet [打印本页]

作者: 李志广    时间: 2012-7-13 18:30
标题: 菜鸟:ArrayList 与hashSet
本帖最后由 007lzg 于 2012-7-14 08:12 编辑

class Person
{
    private String name;
    private int age;
    Person(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
   
    public boolean equals(Object obj)
    {

        if(!(obj instanceof Person))
            return false;

        Person p = (Person)obj;
        //System.out.println(this.name+"....."+p.name);

        return this.name.equals(p.name) && this.age == p.age;
    }
    /**/
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}
class ArrayListTest2
{
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
    public static void main(String[] args)
    {
        ArrayList al = new ArrayList();

        al.add(new Demo());

        al.add(new Person("lisi01",30));//al.add(Object obj);//Object obj = new Person("lisi01",30);
        //al.add(new Person("lisi02",32));
        al.add(new Person("lisi02",32));
        al.add(new Person("lisi04",35));
        al.add(new Person("lisi03",33));
        //al.add(new Person("lisi04",35));

        
        //al = singleElement(al);

        sop("remove 03 :"+al.remove(new Person("lisi03",33)));//remove方法底层也是依赖于元素的equals方法。


        Iterator it = al.iterator();


        while(it.hasNext())
        {
            Person p = (Person)it.next();
            sop(p.getName()+"::"+p.getAge());
        }
    }


    public static ArrayList singleElement(ArrayList al)
    {
        //定义一个临时容器。
        ArrayList newAl = new ArrayList();

        Iterator it = al.iterator();

        while(it.hasNext())
        {
            Object obj = it.next();

            if(!newAl.contains(obj))
                newAl.add(obj);

        }

        return newAl;
    }
}
----------------------------------------------------------------
class HashSetTest
{
    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
    public static void main(String[] args)
    {
        HashSet hs = new HashSet();

        hs.add(new Person("a1",11));
        hs.add(new Person("a2",12));
        hs.add(new Person("a3",13));
//        hs.add(new Person("a2",12));
//        hs.add(new Person("a4",14));

        //sop("a1:"+hs.contains(new Person("a2",12)));
            
//        hs.remove(new Person("a4",13));
        

        Iterator it = hs.iterator();

        while(it.hasNext())
        {
            Person p = (Person)it.next();
            sop(p.getName()+"::"+p.getAge());
        }
    }
}
class Person
{
    private String name;
    private int age;
    Person(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
   
    public int hashCode()
    {
        System.out.println(this.name+"....hashCode");
        return name.hashCode()+age*37;
    }

    public boolean equals(Object obj)
    {

        if(!(obj instanceof Person))
            return false;

        Person p = (Person)obj;
        System.out.println(this.name+"...equals.."+p.name);

        return this.name.equals(p.name) && this.age == p.age;
    }

   
    public String getName()
    {
        return name;
    }
    public int getAge()
    {
        return age;
    }
}

在老师讲解的这两个例子中,都是讲解了ArrayList 与hashSet在自定义的应用。我不明白的是:
这两者有什么区别,它们在实际的应用当中哪一个更方便使用呢?

作者: 鲍霄霄    时间: 2012-7-13 18:43
arraylist有顺序,
hashset没有顺序。
set没有键值和属性值,那是map
不能说它在那一方便于使用,一般情况下来说:List是一个接口,而ArrayList是一个class,是实现了这个接口的,HashSet,可以按字面上把它分解为两部分,一方面它表示一个集合(Set),另一方面,它的实现使用了散列法(Hashing),所以说它们两所是实现的是不同方面的功能

作者: 游兴钟    时间: 2012-7-13 18:47
List:元素是有序的,元素可以重复。因为该集合体系有索引。
    ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。
    LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
    Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。





Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。
   HashSet:底层数据结构是哈希表。是线程不安全的。不同步。
              是通过元素的两个方法,hashCode和equals来保证元素唯一性的。
              如果元素的HashCode值相同,才会判断equals是否为true。
              如果元素的hashcode值不同,不会调用equals。

              注意:对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。



   TreeSet:可以对Set集合中的元素进行排序。
             底层数据结构是二叉树。线程不同步.
                   保证元素唯一性的依据:通过compareTo方法或者比较器来实现元素的唯一性.



               TreeSet排序的第一种方式:让元素自身具备比较性。
               元素需要实现Comparable接口,覆盖compareTo方法。
               也种方式也成为元素的自然顺序,或者叫做默认顺序。

               TreeSet的第二种排序方式。
               当元素自身不具备比较性时,或者具备的比较性不是所需要的。
               这时就需要让集合自身具备比较性。
               在集合初始化时,就有了比较方式。(比较器)
这时我整理的几种集合的特点,楼主可以参考一下


作者: 孙新强    时间: 2012-7-13 18:55
Set 集合是无序不可以重复的的、List 集合是有序可以重复的。
看一个小例子:

package mark.zhang;

import java.util.ArrayList;
import java.util.HashSet;

public class Test {

    public static void main(String[] args) {
        ArrayList<Integer> loadsList = new ArrayList<Integer>();
        loadsList.add(1);
        loadsList.add(2);
        loadsList.add(0);
        loadsList.add(3);
        loadsList.add(2);
        loadsList.add(1);
        loadsList.add(3);
        loadsList.add(5);
        loadsList.add(0);
        System.out.println("the arrayList: " + loadsList);
      
        HashSet<Integer> loadsSet = new HashSet<Integer>();
        loadsSet.add(1);
        loadsSet.add(2);
        loadsSet.add(0);
        loadsSet.add(3);
        loadsSet.add(2);
        loadsSet.add(1);
        loadsSet.add(3);
        loadsSet.add(5);
        loadsSet.add(0);
        System.out.println("the hashSet:   " + loadsSet);
    }
}
代码很简单,分别使用 ArrayList、HashSet 装载 Integer 数据,然后打印集合的内容。


List 中的元素是按照 add 顺序加载的,并且里面有重复的元素。这就是有序可重复的意思。
Set 中的元素并没有按照 add 顺序加载的,并且里面没有重复的元素。这就是无序不可重复的意思。

换句话说,有序不是指按照字母顺序或者数字大小来排列的,重复是指元素之间 equals 为 true。

这里选择 Integer,因为其重写了 equals 方法。


作者: 黑马振鹏    时间: 2012-7-13 18:59
HashSet不能存放重复元素,ArrayList可以存放重复的元素。区别就在于HashSet集合用了Hash算法,向它里面存放的时候,需要用Hash算法对将要存入的对象和已经存入的对象进行比较。如果发现相同就没法存进去,而ArrayList不需要,它可以存取相同的对象。
    Java基础加强里老师提到了,内存泄露。提示

(1)通常来说,一个类的两个实例对象用equals( )方法比较的结果相等时,他们的哈希码也

必须相等,但反之则不成立,即equals方法比较不相等的对象可以有相同的哈希码,或者说哈希

码相同的两个对象的equals方法比较的结果可以不等,例如,“BB”和“AA”的equals

方法比较结果肯定不相等,但他们的hashCode方法返回值却相等。

(2)当一个对象被存储进HashSet集合以后,就不能修改这个对象中那些参与计算哈希值的字段了

,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下

即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回

找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,从而造成内存泄露。


作者: 杨康    时间: 2012-7-13 19:24
ArrayList底层数据结构是数组,Hashmap底层数据结构是哈希表,ArrayLish因为是数组,可以有重复元素,而且是有序的。
Hashmap则是无序,而且不可以有城府元素。
作者: 王飞    时间: 2012-7-13 19:34
ArrayList 与hashSet 是两个不同的派系: List和Set
List有序 ,   Set无序

List和数组差不多,里面装的对象可以重复,可以通过数组角标获取相应的对象
Set里面装的对象不能重复,重复add的话是添加不进去的


有序用List系的
无序用Set系的


如果是键值对形式,那就用map集合







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