容器

来源:互联网 发布:win平板装ubuntu 编辑:程序博客网 时间:2024/06/05 00:46

迭代器

在使用iterator()时会经常遇到ConcurrentModificationException异常,这通常是由于在使用Iterator遍历的同时又使用Collection.add对容器做增加或者删除的操作所导致的,或者由于多线程操作导致的。

        public E next() {            checkForComodification();            int i = cursor;            if (i >= size)                throw new NoSuchElementException();            Object[] elementData = ArrayList.this.elementData;            if (i >= elementData.length)                throw new ConcurrentModificationException();            cursor = i + 1;            return (E) elementData[lastRet = i];        }
        final void checkForComodification() {            if (modCount != expectedModCount)                throw new ConcurrentModificationException();        }

当调用iterator()返回Iterator对象时,expectedModCount等于此刻容器中元素的个数。在调用next()时会比较modCount != expectedModCount。因此在使用Iterator遍历容器的过程中,如果对容器进去增加或删除操作,就会改变容器中元素的数量,即modCount。

解决方法:

  • 使用ListIterator.add
  • 使用Iterator.remove或ListIterator.remove
  • 遍历过程中将需要删除的对象保存到另一个集合,遍历结束后调用removeAll()

多线程访问容器的过程中抛出ConcurrentModificationException解决方法:

  • 使用线程安全的容器,比如ConcurrentHashMap和CopyOnWriteArrayList
  • 在使用迭代器遍历容器时对容器的操作放到synchronized代码中,但是当引用程序并发程度比较高时,会严重影响程序的性能。

ArrayList、Vector和LinkedList

Vector是线程安全的,ArrayList不是线程安全的,所以Vector性能上略逊于ArrayList。


HashMap、Hashtable、TreeMap、LinkedHashMap和WeakHashMap

HashMap和Hashtable都采用hash法进行索引,主要区别:

  1. HashMap非线程安全,允许空键值,但最多只允许一条记录的键为null。
  2. HashMap把Hashtable的contains方法去掉了,改成containsValue和containsKey。Hashtable继承自Dictionary类。
  3. Hashtable的方法是线程安全的。
  4. Hashtable中Hash数组默认大小是11,增加的方式是old*2+1。在HashMap中,Hash数组默认大小是16,而且一定是2的指数。
  5. 两者采用的hash/rehash算法几乎一样。
  6. hash值的使用不同,Hashtable直接使用对象的hashCode。

WeakHashMap中key采用的是“弱引用”的方式,只要key不再被外部引用,它就可以被垃圾回收器回收。而HashMap中key采用“强引用的方式”,只有key从HashMap中删除后,才会被回收。

如何实现HashMap的同步?    Map map1 = Collections.synchronizedMap(new HashMap<>());

用自定义类型作为HashMap或Hashtable的key

重写key对象的hashCode()和equals()方法如果两个对象相等,则其hashCode也相等
package containers;import java.util.HashMap;import java.util.Iterator;import java.util.Map;/** * Created by mook on 2017/5/3. */class Person {    String id;    String name;    public Person(String id, String name) {        this.id = id;        this.name = name;    }    @Override    public String toString() {        return "id= " + id + ",name= " + name;    }    @Override    public boolean equals(Object o) {        if (this == o) return true;        if (o == null || getClass() != o.getClass()) return false;        Person person = (Person) o;        if (id != null ? !id.equals(person.id) : person.id != null) return false;        return name != null ? name.equals(person.name) : person.name == null;    }    @Override    public int hashCode() {        int result = id != null ? id.hashCode() : 0;        result = 31 * result + (name != null ? name.hashCode() : 0);        return result;    }}public class mapKey {    public static void test() {        Map<String,String> map = new HashMap<>();        map.put(null,null);        map.put("abc",null);        map.put("zxc","ni");        map.put("zxc","huai");        System.out.println(map);        Iterator iterator = map.entrySet().iterator();        while (iterator.hasNext()) {            Map.Entry entry = (Map.Entry) iterator.next();            String key = (String) entry.getKey();            String value = (String) entry.getValue();            System.out.println(key + "   " + value);        }    }    public static void testPerson() {        Map<Person,String> map = new HashMap<>();        Person p1 = new Person("111", "rose");        Person p2 = new Person("111", "rose");        map.put(null,null);        map.put(p1, "address1");        map.put(p2, "address2");        System.out.println(map);        Iterator iterator = map.entrySet().iterator();        while (iterator.hasNext()) {            Map.Entry entry = (Map.Entry) iterator.next();            Person key = (Person) entry.getKey();            String value = (String) entry.getValue();            System.out.println(key + "   " + value);        }    }    public static void main(String[] args) {        test();        testPerson();    }}
**output:**{null=null, abc=null, zxc=huai}null   nullabc   nullzxc   huai{null=null, id= 111,name= rose=address2}null   nullid= 111,name= rose   address2

Collection和Collections

0 0
原创粉丝点击