colloection-map,set集合

基础类


package com.yh.container;


public class Student {

private String sno;
private String name;
private int age;
private String sex;

public Student(String sno,String name,int age,String sex){
this.sno=sno;
this.name=name;
this.age=age;
this.sex=sex;
}


public String getSno() {
return sno;
}
public void setSno(String sno) {
this.sno = sno;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setAge(int age) {
this.age = age;
}






//重写 :继承关系, 子类重写父类的方法
@Override
public boolean equals(Object obj){
//obj 和当前对象指向同一块内存
if(obj==this){
return true;
}

if(obj==null){
return false;
}


/* if(this.getClass()==obj.getClass()){

}*/

//两个对象是同一个实例,实例的所有属性值相等
if(obj instanceof Student){
Student stu=(Student)obj;
if(stu.getSno()!=null && this.sno.equals(stu.getSno()) && stu.getName()!=null && this.name.equals(stu.getName()) && this.age==stu.getAge()){
return true;
}
}

return false;

}

//重写hashcode
@Override
    public int hashCode(){
  return sno.hashCode()+name.hashCode()+String.valueOf(age).hashCode();
    }


}


package com.yh.container;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


/*
 * Collection 是根接口  List,Set子接口
 * List 子类:ArrayList,Vector,LinkedList
 * 
 * Collection对象的创建,通过子类
 * collection 常用方法:
 * boolean add(Object object) 在集合末尾添加元素
 * 
 * boolean contains(Object o)   如果此 collection 包含指定的元素,则返回 true。 
   boolean isEmpty()   判断容器是否为空
   boolean remove(Object o) 从容器删除制定的元素
   boolean clear() 删除容器中所有的元素
   int size()  返回容器中元素的个数
  
  Iterator iterator() 迭代器 对容器中的元素进行迭代
  boolean hasNext()  如果仍有元素可以迭代,则返回 true。 
  E next()   返回迭代的下一个元素。  
        
 */ 


public class TestCollection01 {


public static void main(String[] args) {
// TODO Auto-generated method stub

//创建Collection对象

Collection collection=new ArrayList();

int a=10;
String str1="hello Word!";
boolean flag=true;

Student zhangsan=new Student("10001","张三",23,"男");

//add()方法,添加元素
collection.add(10); 
collection.add(str1);
collection.add(flag);
collection.add(zhangsan);

//contains(Object object) 是否包含指定的元素
System.out.println("是否包含hello Word!="+collection.contains("hello Word!"));
System.out.println("是否包含true="+collection.contains(true));
System.out.println("是否包含Integer(10)="+collection.contains(new Integer(10)));

System.out.println("是否包含张三="+collection.contains(new Student("10001","张三",23,"男")));


System.out.println("删除之前容器是否为空:"+collection.isEmpty());

System.out.println("删除前容器中元素个数:"+collection.size());

//remove 删除元素
/* System.out.println("删除元素:"+collection.remove(new Integer(10)));
collection.remove("hello Word!");
collection.remove(true);
collection.remove(new Student("10001","张三",23,"男"));
*/

//isEmpty() 判断容器是否为空
System.out.println("删除之后容器是否为空:"+collection.isEmpty());

//size() 返回容器中元素个数
System.out.println("删除后容器中元素个数:"+collection.size());

//清空容器中所有的元素
// collection.clear();

//Iterator 迭代器堆collection中元素进行迭代 hasNext() next()
Iterator it=collection.iterator();
 
while(it.hasNext()){
System.out.println("迭代:"+it.next());
}

 
 
}


}




package com.yh.container;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


/*
 * Colelction 高级方法
 * boolean addAll(Collection c) 往此 collection 容器添加指定容器c中所有的元素
 * boolean containsAll(Collection c) 如果此 collection 包含指定 collection c中的所有元素,则返回 true。 
 * boolean removeAll(Collection c)   删除此 collection 中那些也包含在指定 collection c 中的所有元素  
   boolean retainAll(Collection c)   仅保留此 collection 中那些也包含在指定 collection c的元素
 
 */


public class TestCollection02 {


public static void main(String[] args) {
// TODO Auto-generated method stub

Collection collection1=new ArrayList();

collection1.add("高子超");
collection1.add("高可超");

collection1.add("朱豪杰");

System.out.println("容器1元素个数:"+collection1.size());

Collection collection2=new ArrayList();

collection2.add("李宁");

collection2.add("王毅");
collection2.add("李昂");

//addAll(Collection c)
collection1.addAll(collection2);

Iterator it=collection1.iterator();

while(it.hasNext()){
System.out.println("容器1元素:"+it.next());
}

        Collection collection3=new ArrayList();

collection3.add("高子超");
collection3.add("高可超");

collection3.add("王文光");
//collection3.add("朱豪杰");

System.out.println("collection1 是否包含collection3所有元素:"+collection1.containsAll(collection3));


Collection collection4=new ArrayList();

collection4.add("高子超");
collection4.add("高可超");
collection4.add("王文光");

collection1.removeAll(collection4);

Iterator it2=collection1.iterator();

while(it2.hasNext()){
System.out.println("容器1删除容器4中所有的元素:"+it2.next());
}

Collection collection5=new ArrayList();

collection5.add("李昂");

collection5.add("高可超");

collection1.retainAll(collection5);

  Iterator it3=collection1.iterator();

while(it3.hasNext()){
System.out.println("容器只保留容器collection5中所有的元素:"+it3.next());
}

}


}





package com.yh.container;


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


/*
 * List :动态数组 实现类:ArrayList,Vector,LinkedList 
 * list 集合的特性:元素可重复,且有序,元素可以为null
 * 独有的方法:
 * get(index x) 根据索引取值
 * Itertor iterator() 迭代器遍历,但不能修改元素
 * for循环,
 * set(int index,Value value)  用指定的元素替代此列表中指定位置上的元素。
 * 
 * int indexOf(Object o)    返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。 
   int lastIndexOf(object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
   remove(Object obj) 移除此列表中首次出现的指定元素
   remove(index inx) 移除此列表中指定位置上的元素
 */
public class TestList03 {


public static void main(String[] args) {
// TODO Auto-generated method stub

List list=new ArrayList();

list.add(10);
list.add("Tom");
list.add(true);
        list.add("hello");
        list.add(10);
        list.add("Tom");
        list.add(null);
        
        System.out.println("元素个数:="+list.size());
        //获取第一个元素
        System.out.println(list.get(0));
        
        //获取最后一个元素
        System.out.println(list.get(list.size()-1));
        
        //迭代器遍历list 
        
        Iterator it=list.iterator();
        while(it.hasNext()){
        System.out.println("元素:"+it.next());
        }
        
        list.set(0, 100);


         //for循环遍历 
        for(int i=0;i<list.size();i++){
        System.out.println("循环遍历元素:"+list.get(i));
        }
        
        //增强for循环
        for(Object obj : list){
        System.out.println("增强for遍历元素:"+obj);
        }
        
       
      //"hello"在list首次出现的位置,返回 索引
      System.out.println(list.indexOf("hello"));
      
      //
      System.out.println("Tom在list首次出现的位置 :"+list.indexOf("Tom"));
      System.out.println("Tom在list最后出现的位置 :"+list.lastIndexOf("Tom"));
      System.out.println("Tom在list最后出现的位置 :"+list.lastIndexOf("tom"));
      System.out.println("删除Tom前元素个数 :"+list.size());
      
     //根据指定的元素删除
      /*  list.remove("Tom");
      //根据索引删除元素
      list.remove(list.lastIndexOf("Tom"));
      System.out.println("删除Tom后元素个数 :"+list.size());*/
      
      //查找容器中是否由Tom,换成Lucy
      for(int i=0;i<list.size();i++){
     if(list.get(i)!=null && list.get(i).equals("Tom")){
     list.set(i, "Lucy");
     }
     if(list.get(i)==null){
    list.set(i, "");
     }
      }
      
      for(Object obj : list){
     System.out.println("Tom换成Lucy:"+obj);
      }
      
      
}


}






package com.yh.container;


import java.util.HashSet;
import java.util.Iterator;
import java.util.TreeSet;


/**
 * Set接口 :元素无序,且元素不可重复, 允许使用 null 元素 实现类:HashSet,TreeSet,LinkedHashSet
 * HashSet实例化 new HashSet()
 *add() 添加元素
 *    
 *遍历 :Iterator iterator() HashSet类中没有提供根据集合索引获取索引对应的值的方法,  因此遍历HashSet时需要使用Iterator迭代器
 *
 *TreeSet 字母的自然顺序排列
 *LinkedHashSet 元素添加时的顺序
 *
 */
public class TestSet07 {


public static void main(String[] args) {
// TODO Auto-generated method stub


HashSet hashSet=new HashSet();

hashSet.add(10);
hashSet.add(true);
hashSet.add(new Person("张三",21));
hashSet.add(10);
hashSet.add(null);
hashSet.add(new Person("张三",21));

System.out.println(hashSet.size());

Iterator it=hashSet.iterator();
while(it.hasNext()){
System.out.println(it.next());
}


TreeSet set = new TreeSet();
set.add("kkkkk");
set.add("ddddd");
set.add("vvvvv");
set.add("eeeee");
        set.add("kkkkk");             
        System.out.println(set);



}


}




package com.yh.container;


import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;




/*
 * Map 接口  Map中以键-值对 形式存储数据   实现类 : HashMap,Properties,HashTable
 * 键 不可以重复,值可以重复 
 * put(Object key, Object value)  
 * get(Object key)  返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
 * remove(Object key)  如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。 
 *  boolean containsKey(Object key) 如果此映射包含指定键的映射关系,则返回 true。 
    boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true。 
    int size() 返回此映射中的键-值映射关系数。 
 *  Collection<V> values()  返回此映射中包含的值的 Collection 视图。
 *  Set keySet()  返回此映射中包含的键的 Set 视图。
 *  Set entrySet() 返回此映射中包含的映射关系(key-value)的 Set 视图。 
 *  
 *   boolean isEmpty() 如果此映射未包含键-值映射关系,则返回 true。 
 */
public class Test08Map {


public static void main(String[] args) {
// TODO Auto-generated method stub


Map map=new HashMap();
System.out.println("map 集合是否为空:"+map.isEmpty());



map.put("lucy", 12522252552l);
map.put("10001", new Person("Tom",20));
map.put("10002", new Person("Tom",20));
map.put("10002", new Person("jack",21));
map.put(1, "张三");

System.out.println("map 集合是否为空:"+map.isEmpty());

//key-value 个数
System.out.println("键值对个数 :"+map.size());


System.out.println(map.get(1));
System.out.println(map.get("lucy"));
System.out.println(map.get("10001"));

        System.out.println(map.get(2));  //不包含该键的映射关系,则返回 null
       
       System.out.println("map集合是否包含10001的key:"+map.containsKey("10001"));
       System.out.println("map集合是否包含10002的key:"+map.containsKey("10002"));
       
       System.out.println("map集合是否包含张三的value:"+map.containsValue("张三"));
       System.out.println("map集合是否包含Tom的value:"+map.containsValue(new Person("Tom",20)));

       //对Map的value进行遍历
  Collection cl1=map.values();
  Iterator it=cl1.iterator();
  while(it.hasNext()){
  System.out.println("map 的Value集合元素 :"+it.next());
  }
  
  //对Map的Key进行遍历
  Set set=map.keySet();
  Iterator it2=set.iterator();
  while(it2.hasNext()){
  System.out.println("map 的key集合元素 :"+it2.next());
  }
 
/*   //把名字叫"张三"的人删除掉
  Set deleteZhangsan=map.keySet();
  Iterator itTemp=deleteZhangsan.iterator();
  while(itTemp.hasNext()){
  Object key=itTemp.next();
//根据key 获取value 判断value值是否是"张三"
       if(map.get(key).equals("张三")){
      //删除"张三"对应的key
    //   map.remove(key);
     // return 
       }
       
  }*/
  
  
  //堆map 的key-value 进行迭代
  Set setKeyValue=map.entrySet();
  Iterator it3=setKeyValue.iterator();
  while(it3.hasNext()){
  System.out.println("map 的key-value映射:"+it3.next());
  }
  
}


}




根本原因

以上都有3种出现异常的情况有一个共同的特点,都是使用Iterator进行遍历,且都是通过ArrayList.remove(Object) 进行删除操作。
想要找出根本原因,直接查看ArrayList源码看为什么出现异常:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

public class ArrayList<e> extends AbstractList<e>

        implements Cloneable, Serializable, RandomAccess {

         

         

         @Override public boolean remove(Object object) {

        Object[] a = array;

        int s = size;

        if (object != null) {

            for (int i = 0; i < s; i++) {

                if (object.equals(a[i])) {

                    System.arraycopy(a, i + 1, a, i, --s - i);

                    a[s] = null// Prevent memory leak

                    size = s;

                    modCount++;  // 只要删除成功都是累加

                    return true;

                }

            }

        } else {

            for (int i = 0; i < s; i++) {

                if (a[i] == null) {

                    System.arraycopy(a, i + 1, a, i, --s - i);

                    a[s] = null// Prevent memory leak

                    size = s;

                    modCount++;  // 只要删除成功都是累加

                    return true;

                }

            }

        }

        return false;

    }  

 

 

    @Override public Iterator<e> iterator() {

        return new ArrayListIterator();

    }  

         

    private class ArrayListIterator implements Iterator<e> {

          ......

    

          // 全局修改总数保存到当前类中

        /** The expected modCount value */

        private int expectedModCount = modCount;

 

        @SuppressWarnings("unchecked") public E next() {

            ArrayList<e> ourList = ArrayList.this;

            int rem = remaining;

               // 如果创建时的值不相同,抛出异常

            if (ourList.modCount != expectedModCount) {

                throw new ConcurrentModificationException();

            }

            if (rem == 0) {

                throw new NoSuchElementException();

            }

            remaining = rem - 1;

            return (E) ourList.array[removalIndex = ourList.size - rem];

        }  

         

          ......

     }

}   </e></e></e></e></e>


List、Set、Map 都可以通过Iterator进行遍历,这里仅仅是通过List举例,在使用其他集合遍历时进行增删操作都需要留意是否会触发ConcurrentModificationException异常。

3. 解决方案

map.remove() 改:iterator.remove()

 

使用Iterator遍历集合时,不要改动被迭代的对象,可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护modCount和expectedModCount值的一致性。

 

 

 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值