沉睡森林@漂在北京

本处文章除注明“转载”外均为原创,转载请注明出处。

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  152 随笔 :: 4 文章 :: 114 评论 :: 0 Trackbacks

关于Collection接口下相关类接口的问题及分析

 

*List*Set的异同

ListSet本身都是接口,他们都继承了Collection接口,分别表示2种数据机构。一种*List可以有重复的数据,可以有多个NULL值;而另外一种*Set不能有重复数据,最多只能有一个NULL值。在他们的源代码上可以很清楚的发现这些差异。

可以打开ArrayListadd方法代码如下:

public boolean add(E e) {

      ensureCapacity(size + 1);  // Increments modCount!!

      elementData[size++] = e;

      return true;

}

HashSetadd方法代码如下:

public boolean add(E e) {

      return map.put(e, PRESENT)==null;

}

一个是数组实现,一个使用Map实现,并且HashSet的元素作为mapkey值,必然不能重复。

 

关于ArrayListVector的异同

       ArrayList不是线程安全的,而Vector是的。具体可以看Vectoradd方法和insertElementAt方法的代码:

public void add(int index, E element) {

        insertElementAt(element, index);

}

    public synchronized void insertElementAt(E obj, int index) {

      modCount++;

      if (index > elementCount) {

          throw new ArrayIndexOutOfBoundsException(index

                                       + " > " + elementCount);

      }

      ensureCapacityHelper(elementCount + 1);

      System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);

      elementData[index] = obj;

      elementCount++;

    }

       代码里面有大家熟悉的synchronized关键字,说明进行了线程同步。而ArrayList中的add方法没有进行同步,自然不是线程安全的。如果需要使用ArrayList且需要同步可以使用如下代码:

List list = Collections.synchronizedList(new ArrayList());

 

 

ArrayList,Vector,  LinkedList的存储性能和特性

ArrayListVector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。

 

关于CollectionsCollection的区别

Collection是集合类的上级接口,继承与他的接口主要有Set  ListCollections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

 

 

关于HashMapHashTable的异同

       都是实现了Map接口,利用keyvalue对应存取对象,都是基于Hash算法实现快速存取。但是HashTable是线程安全的,HashMap不是,在效率上因为同步的原因有所差异。并且,HashMap中的key可以有NULL但最多一个,而HashTable不能有NULLkey值。

       HashMapput方法代码如下:

public V put(K key, V value) {

        if (key == null)

            return putForNullKey(value);

        int hash = hash(key.hashCode());

        int i = indexFor(hash, table.length);

        for (Entry<K,V> e = table[i]; e != null; e = e.next) {

            Object k;

            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {

                V oldValue = e.value;

                e.value = value;

                e.recordAccess(this);

                return oldValue;

            }

        }

        modCount++;

        addEntry(hash, key, value, i);

        return null;

    }

       HashTableput方法代码如下:

public synchronized V put(K key, V value) {

      // Make sure the value is not null

      if (value == null) {

          throw new NullPointerException();

      }

      // Makes sure the key is not already in the hashtable.

      Entry tab[] = table;

      int hash = key.hashCode();

      int index = (hash & 0x7FFFFFFF) % tab.length;

      for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {

          if ((e.hash == hash) && e.key.equals(key)) {

           V old = e.value;

           e.value = value;

           return old;

          }

      }

      modCount++;

      if (count >= threshold) {

          // Rehash the table if the threshold is exceeded

          rehash();

 

            tab = table;

            index = (hash & 0x7FFFFFFF) % tab.length;

      }

      // Creates the new entry.

      Entry<K,V> e = tab[index];

      tab[index] = new Entry<K,V>(hash, key, value, e);

      count++;

      return null;

    }

 

posted on 2010-04-26 11:43 王总兵 阅读(283) 评论(0)  编辑  收藏 所属分类: Other

只有注册用户登录后才能发表评论。


网站导航: